diff --git a/404.html b/404.html new file mode 100644 index 00000000..2d1faa52 --- /dev/null +++ b/404.html @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

404

+

Page not found

+

Home

+
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/Introduction/index.html b/Introduction/index.html new file mode 100644 index 00000000..132da9c0 --- /dev/null +++ b/Introduction/index.html @@ -0,0 +1,469 @@ + + + + + + + + + + + + + + Introduction - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

A human's guide to the Lottie format

+

Lottie is a vector animation format, using JSON to represent its data.

+

This guide aims to provide a human-readable description of the format and how +everything works within it.

+

This documentation assumes the reader is already familiar with the following concepts:

+ +

What this guide is

+

This guide aims to describe the lottie format in its entirety, while also give +in-depth descriptions of how every aspect works, which you can't get from just +looking at a list of JSON attributes.

+

It contains a section that shows a breakdown of +simple lottie animation describing what is going on as an introduction for the format.

+

It also has reference pages which go over the details of every object +you can find in a lottie file, and a description of its most notable attributes.

+

It provides a complete JSON schema, this is intended +for people who want to write tools to parse or generate lottie and need to get +every little detail.

+

Finally it has a section with details about rendering, +which gives tips and provides pseudo-code on how to draw various elements to +match with the lottie web player.

+

What this guide is not

+

You won't find here information on how to animate, or how to export a lottie +file from your editor of choice.

+

It also won't give information on how to embed lottie animations in your +application or website.

+

This is because there's already a lot of documentation for creating and using +lottie animations, while this aims at providing a description of the file format itself.

+

For the Impatient

+

The top level JSON object is the Animation.

+

Note that some lottie players require certain JSON keys to be presents before others in the file +to play properly.

+

Objects within the JSON may have a mixture of animatable and non-animatable properties.

+

If a property is not animated, the value is represented as usual within the JSON. +If it's animated, it has a special representation.

+

Interactive Explanation

+

If you have a lottie animation and you want to see an interactive description +of its contents, you can visit the JSON Editor page.

+

Anatomy of a Lottie file

+

Go to the next page for a breakdown of a simple +lottie animation.

+

JSON Schema

+

This guide provides a human-readable description of the format, but if you want +a machine-readable description, we also have a JSON schema.

+

Other Resources

+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/advanced_interactions/index.html b/advanced_interactions/index.html new file mode 100644 index 00000000..36375f9c --- /dev/null +++ b/advanced_interactions/index.html @@ -0,0 +1,4842 @@ + + + + + + + + + + + + + + Advanced Interactions - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Advanced Interactions

+

This page will describe how to create lotties with advanced interactivity, +specifically when used with lottie-web player.

+

This page is divided into "levels", each level adds more obscure features +which are less portable but add increased interaction capabilities.

+

There are 9 levels below Regular Lottie, which is the same as the +number of circles of hell in Dante's Inferno. Reader discretion is advised.

+

The techniques described below require knowledge on the following topics:

+ + + +

Level 0: Regular Lotties

+

Lotties can play an animation, loading an animation looks something like this:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 360,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [256, 256]},
+                    "or": {"a": 0, "k": 200},
+                    "ir": {"a": 0, "k": 100},
+                    "r": {"a": 1, "k": [
+                        {"t": 0, "s": [0], "o": {"x": 0, "y": 0}, "i": {"x": 1, "y": 1}},
+                        {"t": 360, "s": [360]}
+                    ]},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "st",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [1, 1, 0.3]},
+                    "lc": 2,
+                    "lj": 2,
+                    "ml": 0,
+                    "w": {"a": 0, "k": 30}
+                }
+            ]
+        }
+    ]
+}
+
<div id="level0"></div>
+
var container = document.getElementById("level0");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+
+

By themselves lotties just play an animation, but luckily lottie-web provides some utility functions, +note how in the Script above we are storing the variable anim returned by bodymovin.loadAnimation.

+

Level 1: Controlling Playback

+

You can play around with the anim object like setting the current frame, pausing stopping etc.

+

There's also the LottieFiles interactivity library +that makes some of these interactions easier to create.

+

Here's an example of a lottie changing based on mouse position:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 360,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [256, 256]},
+                    "or": {"a": 0, "k": 200},
+                    "ir": {"a": 0, "k": 100},
+                    "r": {"a": 1, "k": [
+                        {"t": 0, "s": [0], "o": {"x": 0, "y": 0}, "i": {"x": 1, "y": 1}},
+                        {"t": 360, "s": [360]}
+                    ]},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "st",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [1, 1, 0.3]},
+                    "lc": 2,
+                    "lj": 2,
+                    "ml": 0,
+                    "w": {"a": 0, "k": 30}
+                }
+            ]
+        }
+    ]
+}
+
<div id="level1"></div>
+
var container = document.getElementById("level1");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: false,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+container.addEventListener("mousemove", ev => {
+    var rect = container.getBoundingClientRect();
+    var t = (ev.clientX - rect.left) / rect.width;
+    anim.goToAndStop(t * json.op, true);
+});
+
+
+

Level 2: SVG Styling

+

When using the SVG renderer, you can make use of CSS styling by specifying +a value for cl in the lottie layers.

+

In the example below, CSS rules highlight the lottie layer showing a rectangle when the mouse is over it.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 360,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "el",
+                    "p": {"a": 0, "k": [400, 300]},
+                    "s": {"a": 0, "k": [150, 150]},
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [0.769, 0.851, 0.961]}
+                }
+            ]
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "cl": "lottie_level_2",
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "p": {"a": 0, "k": [256, 256]},
+                    "s": {"a": 0, "k": [256, 128]},
+                    "r": {"a": 0, "k": 3},
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [0.196, 0.314, 0.69]}
+                }
+            ]
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "el",
+                    "p": {"a": 0, "k": [100, 200]},
+                    "s": {"a": 0, "k": [150, 150]},
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [0.769, 0.851, 0.961]}
+                }
+            ]
+        }
+    ]
+}
+
.lottie_level_2:hover {
+    opacity: 10%;
+}
+.lottie_level_2 {
+    cursor: pointer;
+}
+
<div id="level2"></div>
+
var container = document.getElementById("level2");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: false,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+
+

Level 3: Basic Expressions

+

Lotties can have expressions, they are basically small +snippets of JavaScript code used to modify the value of animated properties.

+

Below the star rotation is animated using an expression instead of using keyframes.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 360,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [256, 256]},
+                    "or": {"a": 0, "k": 200},
+                    "ir": {"a": 0, "k": 100},
+                    "r": {"a": 0, "k": 0, "x": "var $bm_rt = time * 60;"},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "st",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [1, 1, 0.3]},
+                    "lc": 2,
+                    "lj": 2,
+                    "ml": 0,
+                    "w": {"a": 0, "k": 30}
+                }
+            ]
+        }
+    ]
+}
+
<div id="level3"></div>
+
var container = document.getElementById("level3");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+
+

Level 4: Advanced Expressions

+

Within expressions you can access properties from other layers, and since +they are all JavaScript objects, you can add your own properties to them.

+

You can make a layer follow the position of another:

+
// Set the layer position to follow the X position of another layer
+var other_position = thisComp("layer_name").transform.position;
+var $bm_rt = [other_position[0], value[1]];
+
+

Since property values are initialized to their non-expression value, +you can't access updated value of the property you are changing from the +expression. However you can work around this by storing state in the +layer object.

+
// Get size of the rect
+var size = thisLayer.content(1).size;
+
+// Initialize everything at the start
+if ( time == 0 )
+{
+    thisLayer.my_value = size[0] / 2;
+    thisLayer.speed = 60;
+    thisLayer.direction = 1;
+    thisLayer.prev_time = 0;
+}
+
+// Handle the case when the lottie has looped and time has reset
+// as it might not be exactly 0
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+
+// Find the time delta to keep constant speed
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+// Increment x
+thisLayer.my_value += dt * thisLayer.speed * thisLayer.direction;
+var x = thisLayer.my_value;
+if ( x >= thisComp.width - size[0] / 2)
+    thisLayer.direction = -1;
+else if ( x <= size[0] / 2 )
+    thisLayer.direction = 1;
+
+// Calculate y based on x
+var y = value[1] + Math.sin((x / thisComp.width) * Math.PI * 2) * (thisComp.height - size[1]) / 2;
+
+var $bm_rt = [x, y];
+
+

Here's an example:

+

Note that the JSON uses ECMAScript's backtick string syntax for clarity, +in a real Lottie file you'd need to put it into a single line.

+

Newlines in the expression string work fine as long as the last line of +the expression doesn't end in a single line comment.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "nm": "layer_name",
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [0, 256],
+                    "x": `
+// Get size of the rect
+var size = thisLayer.content(1).size;
+
+// Initialize everything at the start
+if ( time == 0 )
+{
+    thisLayer.my_value = size[0] / 2;
+    thisLayer.speed = 120;
+    thisLayer.direction = 1;
+    thisLayer.prev_time = 0;
+}
+
+// Handle the case when the lottie has looped and time has reset
+// as it might not be exactly 0
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+
+// Find the time delta to keep constant speed
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+// Increment x
+thisLayer.my_value += dt * thisLayer.speed * thisLayer.direction;
+var x = thisLayer.my_value;
+if ( x >= thisComp.width - size[0] / 2)
+    thisLayer.direction = -1;
+else if ( x <= size[0] / 2 )
+    thisLayer.direction = 1;
+
+// Calculate y based on x
+var y = value[1] + Math.sin((x / thisComp.width) * Math.PI * 2) * (thisComp.height - size[1]) / 2;
+
+var $bm_rt = [x, y];
+`
+                }
+            },
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "s": {"a": 0, "k": [80, 80]},
+                    "r": {"a": 0, "k": 3},
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [0.196, 0.314, 0.69]}
+                }
+            ]
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 3600,
+            "st": 0,
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [0, 256],
+                    "x": `
+// Set the layer position to follow the X position of another layer
+var other_position = thisComp("layer_name").transform.position;
+var $bm_rt = [other_position[0], value[1]];
+`
+                }
+            },
+            "shapes": [
+                {
+                    "ty": "el",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "s": {"a": 0, "k": [150, 150]},
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [0.769, 0.851, 0.961]}
+                }
+            ]
+        }
+    ]
+}
+
<div id="level4"></div>
+
var container = document.getElementById("level4");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+
+

Level 5: Breaking Time

+

In the previous examples, we had a condition at the start of some expressions +initializing custom attributes when time is equal to 0.

+
if ( time == 0 )
+    thisLayer.my_property = "some value";
+
+

This works because the first frame is always at time 0 but it isn't a +super reliable check: when the player loops, the time can go back to 0 +which would result in your properties being initialized again.

+

If you want your interactions to carry over across loops, a better +approach is to use a condition where you check for undefined layer +properties:

+
if ( thisLayer.my_property === undefined )
+    thisLayer.my_property = "some value";
+
+

For smooth value increments, we need to properly handle the time +variable within expressions. Similarly to what we've done before the +following example shows how to initialize and update a variable over +time;

+
// Initialization
+if ( thisLayer.last_time === undefined )
+{
+    thisLayer.last_time = time;
+    thisLayer.value = 0;
+    thisLayer.speed = 600;
+}
+
+// Handle looping
+if ( time < thisLayer.last_time )
+    thisLayer.last_time = time;
+
+// `dt` is the time since the last expression evaluation in seconds
+var dt = time - thisLayer.last_time;
+
+// Update the time management variable
+thisLayer.last_time = time;
+
+// Increment
+thisLayer.value = dt * thisLayer.speed;
+
+

This approach allows you to change values regardless of playback speed +and framerate. I also allows you to continue the movement when the +lottie reaches its last frame and starts looping.

+

In the following example, the lottie is set to loop every second but +it keeps going indefinitely because of the time management setup:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "nm": "star",
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "ks": {
+                "p": {"a": 0, "k": [0, 0], "x": `
+// Initialization
+if ( thisLayer.prev_time === undefined )
+{
+    thisLayer.px = thisComp.width / 2;
+    thisLayer.py = thisComp.height / 2;
+
+    thisLayer.dx = 1;
+    thisLayer.dy = 1;
+    thisLayer.prev_time = 0;
+}
+
+// Time management
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+// Animation
+thisLayer.px += thisLayer.dx * dt * 100;
+thisLayer.py += thisLayer.dy * dt * 120;
+
+var radius = thisLayer.content(1).outerRadius;
+if ( thisLayer.px < radius )
+    thisLayer.dx = 1;
+else if ( thisLayer.px > thisComp.width - radius )
+    thisLayer.dx = -1;
+if ( thisLayer.py < radius )
+    thisLayer.dy = 1;
+else if ( thisLayer.py > thisComp.height - radius )
+    thisLayer.dy = -1;
+
+// Set value
+var $bm_rt = [thisLayer.px, thisLayer.py];
+                `}},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "or": {"a": 0, "k": 70},
+                    "ir": {"a": 0, "k": 40},
+                    "r": {"a": 0, "k": 0},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {
+                        "a": 0,
+                        "k": [1, 1, 0.3],
+                    }
+                }
+            ]
+        }
+    ]
+}
+
<div id="level5"></div>
+
var options = {
+    container: document.getElementById("level5"),
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+
+

Level 6: Injecting Data

+

Remember the anim object we get from lottie-web? +It's the key for more advanced interactions.

+

Internally it stores its lottie structure and the objects being passed +to expression as thisComp and thisLayer. Being able to access these +objects allows us to pass data directly to the lottie expressions.

+

The object corresponding to thisComp can be accessed as +anim.renderer.compInterface, and from there you can get the layers +by name or index (see the Composition expression object).

+

In the example below the rotation direction and color of the star change +based on whether the mouse is over the element containing the lottie.

+
// Time management as before
+if ( time == 0 )
+{
+    thisLayer.angle = 0;
+    thisLayer.prev_time = 0;
+}
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+var direction = thisComp.counter_clockwise ? -1 : 1;
+thisLayer.angle += dt * direction * 60;
+var $bm_rt = thisLayer.angle;
+
+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 360,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 360,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [256, 256]},
+                    "or": {"a": 0, "k": 200},
+                    "ir": {"a": 0, "k": 100},
+                    "r": {"a": 0, "k": 0, "x": `
+// Time management as before
+if ( thisLayer.prev_time === undefined )
+{
+    thisLayer.angle = 0;
+    thisLayer.prev_time = 0;
+}
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+var direction = thisComp.mouse_is_over ? -1 : 1;
+thisLayer.angle += dt * direction * 60;
+var $bm_rt = thisLayer.angle;
+                    `},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "st",
+                    "o": {"a": 0, "k": 100},
+                    "c": {
+                        "a": 0,
+                        "k": [1, 1, 0.3],
+                        "x": "var $bm_rt = thisComp.mouse_is_over ? [0.196, 0.314, 0.69] : value;"
+                    },
+                    "lc": 2,
+                    "lj": 2,
+                    "ml": 0,
+                    "w": {"a": 0, "k": 30}
+                }
+            ]
+        }
+    ]
+}
+
<div id="level6"></div>
+
var container = document.getElementById("level6");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+container.addEventListener("mouseenter", () => {
+    anim.renderer.compInterface.mouse_is_over = true;
+});
+container.addEventListener("mouseleave", () => {
+    anim.renderer.compInterface.mouse_is_over = false;
+});
+
+
+

Level 7: Automatic Event Handlers

+

So far the interaction logic has been done by JavaScript on the browser.

+

In this section we'll add all the logic in the JSON itself and write a +wrapper script that sets up the animation.

+

This allows you to have self-contained lotties you can embed in a web +page that will handle events on their own.

+

Lottie JSON Extension

+

First thing is to write the expressions in the Lottie itself.

+

Since Lottie is just a JSON file, it's easy to add custom values:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "events": {
+        "click": "/*event handler code*/"
+    }
+}
+
+

Now we need to add some JavaScript so we can listen to the events +fired by the DOM and execute expressions:

+
for ( let [ev_type, expression] of Object.entries(json.events) )
+{
+    let expression_function = Function("event", expression);
+    container.addEventListener(ev_type, expression_function);
+}
+
+

Preparing Globals

+

While the above would work, we should expose some objects for it to be +useful. The lottie player define a bunch of objects +and functions for expressions, but we don't really +need all of them since the even handlers only need to pass along the information +that an event has occurred.

+

We will define thisComp and time +to be the same as the globals of the same name you'd expect to find an expressions, +and pass them to the event handling function:

+

+function event_handler(ev, expression_function)
+{
+    var thisComp = anim.renderer.compInterface;
+    var time = anim.renderer.renderedFrame / anim.renderer.globalData.frameRate;
+
+    expression_function(ev, thisComp, time);
+}
+
+for ( let [ev_type, expression] of Object.entries(json.events) )
+{
+    let expression_function = Function("event", "thisComp", "time", expression);
+    container.addEventListener(ev_type, ev => event_handler(ev, expression_function));
+}
+
+

After this step, you're all set to hanle DOM events automatically from a lottie. +The next couple steps add some polish to the event interface for a smoother experience.

+

Mouse Events

+

Events like click, mousemove, etc. provide the mouse coordinates, +which you might want to access from within the lottie.

+

By default these coordinates aren't in the same space as the values +inside the lottie so we need to scale them appropriately:

+
function event_handler(ev, expression_function)
+{
+    var thisComp = anim.renderer.compInterface;
+    var time = anim.renderer.renderedFrame / anim.renderer.globalData.frameRate;
+
+    if ( ev.clientX !== undefined )
+    {
+        var rect = container.getBoundingClientRect();
+        ev.lottie_x = (ev.clientX - rect.left) / rect.width * thisComp.width;
+        ev.lottie_y = (ev.clientY - rect.top) / rect.height * thisComp.height;
+    }
+
+    expression_function(ev, thisComp, time);
+}
+
+for ( let [ev_type, expression] of Object.entries(json.events) )
+{
+    let expression_function = Function("event", "thisComp", "time", expression);
+    container.addEventListener(ev_type, ev => event_handler(ev, expression_function));
+}
+
+

Now we can reference the position in the lottie expression:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "events": {
+        "click": `
+var star = thisComp("star");
+star.px = event.lottie_x;
+star.py = event.lottie_y;
+`
+    }
+}
+
+

In the example below you can click to move the star to a given position:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "events": {
+        "click": `
+var star = thisComp("star");
+star.px = event.lottie_x;
+star.py = event.lottie_y;
+`
+    },
+    "layers": [
+        {
+            "ty": 4,
+            "nm": "star",
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "ks": {
+                "p": {"a": 0, "k": [0, 0], "x": `
+// Initialization
+if ( thisLayer.px === undefined )
+{
+    thisLayer.px = thisComp.width / 2;
+    thisLayer.py = thisComp.height / 2;
+}
+
+// Set value
+var $bm_rt = [thisLayer.px, thisLayer.py];
+                `}},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "or": {"a": 0, "k": 70},
+                    "ir": {"a": 0, "k": 40},
+                    "r": {"a": 0, "k": 0},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {
+                        "a": 0,
+                        "k": [1, 1, 0.3],
+                    }
+                }
+            ]
+        }
+    ]
+}
+
<div id="level7_mouse"></div>
+
var container = document.getElementById("level7_mouse");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+function event_handler(ev, expression_function)
+{
+    var thisComp = anim.renderer.compInterface;
+    var time = anim.renderer.renderedFrame / anim.renderer.globalData.frameRate;
+
+    if ( ev.clientX !== undefined )
+    {
+        var rect = container.getBoundingClientRect();
+        ev.lottie_x = (ev.clientX - rect.left) / rect.width * thisComp.width;
+        ev.lottie_y = (ev.clientY - rect.top) / rect.height * thisComp.height;
+    }
+
+    expression_function(ev, thisComp, time);
+}
+
+for ( let [ev_type, expression] of Object.entries(json.events) )
+{
+    let expression_function = Function("event", "thisComp", "time", expression);
+    container.addEventListener(ev_type, ev => event_handler(ev, expression_function));
+}
+
+
+

Keyboard Events

+

To allow keyboard events to be fired correctly, you need to ensure the +element containing the lottie is focusable.

+

You can do this by setting the tabindex attribute in HTML or with JavaScript.

+
<div id="level7_keyboard" tabindex="0"></div>
+
+

or

+
container.setAttribute("tabindex", "0");
+
+

In the example below we'll move a layer based on whether the user is +pressing the left and right arrow keys.

+

A good solution for this is to keep track of which key has been pressed +and react accordingly.

+

The event handler code is simple enough:

+

For keydown:

+
if ( event.key == "ArrowLeft" )
+    thisComp("star").left = true;
+else if ( event.key == "ArrowRight" )
+    thisComp("star").right = true;
+
+// Prevent scrolling and other browser shortcuts
+event.preventDefault();
+
+

keyup:

+
if ( event.key == "ArrowLeft" )
+    thisComp("star").left = false;
+else if ( event.key == "ArrowRight" )
+    thisComp("star").right = false;
+
+// Prevent scrolling and other browser shortcuts
+event.preventDefault();
+
+

We should also reset these when the lottie element loses focus:

+

focusout:

+
    thisComp("star").left = false;
+    thisComp("star").right = false;
+
+

We need to add some logic to the layer position property:

+
// Initialization
+if ( thisLayer.px === undefined )
+{
+    thisLayer.px = thisComp.width / 2;
+    thisLayer.py = thisComp.height / 2;
+    thisLayer.left = false;
+    thisLayer.right = false;
+    thisLayer.prev_time = 0;
+}
+// Handle time wrapping around
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+
+// Time delta
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+// Figure which direction to move
+var direction = 0;
+if ( thisLayer.left && thisLayer.right )
+    direction = 0;
+else if ( thisLayer.left )
+    direction = -1;
+else if ( thisLayer.right )
+    direction = 1;
+
+// Move
+if ( direction != 0 )
+{
+    // 600 is the "speed", you need to consider that dt is the time
+    // in seconds since the previous frame so it's usally a rather small value
+    thisLayer.px += direction * dt * 600;
+    var radius = thisLayer.content(1).outerRadius;
+    thisLayer.px = clamp(thisLayer.px, radius, thisComp.width - radius);
+}
+
+// Set value
+var $bm_rt = [thisLayer.px, thisLayer.py];
+
+

The example below shows how to handle keyboard event.

+

Focusing on the element changes the star color. +When focused (blue star) left and right arrow keys move the star in the corresponding direction.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "events": {
+        "keydown": `
+if ( event.key == "ArrowLeft" )
+    thisComp("star").left = true;
+else if ( event.key == "ArrowRight" )
+    thisComp("star").right = true;
+
+// Prevent scrolling and other browser shortcuts
+event.preventDefault();
+`,
+        "keyup": `
+if ( event.key == "ArrowLeft" )
+    thisComp("star").left = false;
+else if ( event.key == "ArrowRight" )
+    thisComp("star").right = false;
+
+// Prevent scrolling and other browser shortcuts
+event.preventDefault();
+`,
+        "focusin": "thisComp.focus = true;",
+        "focusout": `
+    thisComp("star").left = false;
+    thisComp("star").right = false;
+    thisComp.focus = false;
+`,
+    },
+    "layers": [
+        {
+            "ty": 4,
+            "nm": "star",
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "ks": {
+                "p": {"a": 0, "k": [0, 0], "x": `
+// Initialization
+if ( thisLayer.px === undefined )
+{
+    thisLayer.px = thisComp.width / 2;
+    thisLayer.py = thisComp.height / 2;
+    thisLayer.left = false;
+    thisLayer.right = false;
+    thisLayer.prev_time = 0;
+}
+// Handle time wrapping around
+if ( time < thisLayer.prev_time )
+    thisLayer.prev_time = time;
+
+// Time delta
+var dt = time - thisLayer.prev_time;
+thisLayer.prev_time = time;
+
+// Figure which direction to move
+var direction = 0;
+if ( thisLayer.left && thisLayer.right )
+    direction = 0;
+else if ( thisLayer.left )
+    direction = -1;
+else if ( thisLayer.right )
+    direction = 1;
+
+// Move
+if ( direction != 0 )
+{
+    // 600 is the "speed", you need to consider that dt is the time
+    // in seconds since the previous frame so it's usally a rather small value
+    thisLayer.px += direction * dt * 600;
+    var radius = thisLayer.content(1).outerRadius;
+    thisLayer.px = clamp(thisLayer.px, radius, thisComp.width - radius);
+}
+
+// Set value
+var $bm_rt = [thisLayer.px, thisLayer.py];
+                `}},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "or": {"a": 0, "k": 70},
+                    "ir": {"a": 0, "k": 40},
+                    "r": {"a": 0, "k": 0},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {
+                        "a": 0,
+                        "k": [1, 1, 0.3],
+                        "x": "var $bm_rt = thisComp.focus ? [0.196, 0.314, 0.69] : value;"
+                    }
+                }
+            ]
+        }
+    ]
+}
+
<div id="level7_keyboard" tabindex="0"></div>
+
var container = document.getElementById("level7_keyboard");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+function event_handler(ev, expression_function)
+{
+    var thisComp = anim.renderer.compInterface;
+    var time = anim.renderer.renderedFrame / anim.renderer.globalData.frameRate;
+
+    if ( ev.clientX !== undefined )
+    {
+        var rect = container.getBoundingClientRect();
+        ev.lottie_x = (ev.clientX - rect.left) / rect.width * thisComp.width;
+        ev.lottie_y = (ev.clientY - rect.top) / rect.height * thisComp.height;
+    }
+
+    expression_function(ev, thisComp, time);
+}
+
+for ( let [ev_type, expression] of Object.entries(json.events) )
+{
+    let expression_function = Function("event", "thisComp", "time", expression);
+    container.addEventListener(ev_type, ev => event_handler(ev, expression_function));
+}
+
+
+

Level 8: Sound Effects

+

Lottie web supports playing audio layers with the help of Howler.

+

By default the level of control you get with sound is rather limited but +we can find a way around it.

+

The issue is audio layers don't have a scriptable property that controls +playback which means we can't attach an expression to audio layers.

+

The trick is to wrap an audio layer into a precomp and to use an expression +on its time remapping property.

+

We can then control playback as follows:

+
if ( thisLayer.last_time === undefined )
+{
+    thisLayer.last_time = time;
+    // This variable wil control whether the sound is played
+    thisLayer.sound_play = 0;
+    // This should be the time in seconds you want the sound to play for
+    // To get the best results, it should be just short of the duration
+    // of the audio file
+    thisLayer.sound_duration = 1;
+
+}
+// Usual time management stuff
+if ( time < thisLayer.last_time )
+    thisLayer.last_time = time;
+var dt = time - thisLayer.last_time;
+thisLayer.last_time = time;
+
+// Default to not playing
+var $bm_rt = 0;
+
+if ( thisLayer.sound_play > 0 )
+{
+    $bm_rt = thisLayer.sound_duration - thisLayer.sound_play;
+    thisLayer.sound_play -= dt;
+}
+
+

In the example that follows you can click on the lottie to make it play a sound.

+

The precomp also has a green cicle that shows playback progress.

+
{
+    "v": "5.5.2",
+    "fr": 60,
+    "ip": 0,
+    "op": 180,
+    "w": 512,
+    "h": 512,
+    "ddd": 0,
+    "events": {
+        "click": "thisComp('sound_control').sound_play = thisComp('sound_control').sound_duration"
+    },
+    "assets": [
+        {
+            "id": "sound",
+            "u": "/lottie-docs/examples/",
+            "p": "sound.mp3",
+            "e": 0
+        },
+        {
+            "id": "precomp",
+            "layers": [
+                {
+                    "nm": "a",
+                    "ty": 4,
+                    "ip": 0,
+                    "op": 180,
+                    "st": 0,
+                    "ks": {},
+                    "shapes": [
+                        {
+                            "ty": "el",
+                            "p": {"a": 1, "k": [
+                                {
+                                    "t": 0,
+                                    "s": [0, 256],
+                                    "i": {"x": 0, "y": 0},
+                                    "o": {"x": 1, "y": 1},
+                                },
+                                {
+                                    "t": 60,
+                                    "s": [512, 256],
+                                }
+                            ]},
+                            "s": {"a": 0, "k": [100, 100]},
+                        },
+                        {
+                            "ty": "fl",
+                            "c": {"a": 0, "k": [0, 1, 0]},
+                            "o": {"a": 0, "k": 100},
+                        }
+                    ]
+                },
+                {
+                    "ty": 6,
+                    "ip": 1,
+                    "op": 60,
+                    "st": 1,
+                    "refId": "sound",
+                    "au": {
+                        "lv": {"a": 0, "k": [100, 100]}
+                    }
+                }
+            ]
+        }
+    ],
+    "markers": [],
+    "layers": [
+        {
+            "ty": 4,
+            "nm": "star",
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "ks": {},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [256, 256]},
+                    "or": {"a": 0, "k": 70},
+                    "ir": {"a": 0, "k": 40},
+                    "r": {
+                        "a": 1,
+                        "k": [
+                            {
+                                "t": 0,
+                                "s": [0],
+                                "i": {"x": 0, "y": 0},
+                                "o": {"x": 1, "y": 1}
+                            },
+                            {
+                                "t": 180,
+                                "s": [360]
+                            }
+                        ]
+                    },
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {
+                        "a": 0,
+                        "k": [1, 1, 1],
+                        "x": `
+var amount = thisComp('sound_control').sound_play ?? 0;
+var $bm_rt = [amount, 0, 0];
+`,
+                    }
+                }
+            ]
+        },
+        {
+            "nm": "sound_control",
+            "ty": 0,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "ks": {},
+            "refId": "precomp",
+            "w": 512,
+            "h": 512,
+            "tm": {
+                "a": 1,
+                "k": [{
+                        "t": 0,
+                        "s": [0],
+                        "i": {"x": 0, "y": 0},
+                        "o": {"x": 1, "y": 1}
+                    },
+                    {
+                        "t": 180,
+                        "s": [0]
+                    }
+                ],
+                "x": `
+if ( thisLayer.last_time === undefined )
+{
+    thisLayer.last_time = time;
+    // This variable wil control whether the sound is played
+    thisLayer.sound_play = 0;
+    // This should be the time in seconds you want the sound to play for
+    thisLayer.sound_duration = 1;
+
+}
+// Usual time management stuff
+if ( time < thisLayer.last_time )
+    thisLayer.last_time = time;
+var dt = time - thisLayer.last_time;
+thisLayer.last_time = time;
+
+// Default to not playing
+var $bm_rt = 100;
+
+if ( thisLayer.sound_play > 0 )
+{
+    $bm_rt = thisLayer.sound_duration - thisLayer.sound_play;
+    thisLayer.sound_play -= dt;
+}`
+            }
+        }
+    ]
+}
+
+
<div id="level8"></div>
+
var container = document.getElementById("level8");
+var options = {
+    container: container,
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+function event_handler(ev, expression_function)
+{
+    var thisComp = anim.renderer.compInterface;
+    var time = anim.renderer.renderedFrame / anim.renderer.globalData.frameRate;
+
+    if ( ev.clientX !== undefined )
+    {
+        var rect = container.getBoundingClientRect();
+        ev.lottie_x = (ev.clientX - rect.left) / rect.width * thisComp.width;
+        ev.lottie_y = (ev.clientY - rect.top) / rect.height * thisComp.height;
+    }
+
+    expression_function(ev, thisComp, time);
+}
+
+for ( let [ev_type, expression] of Object.entries(json.events) )
+{
+    let expression_function = Function("event", "thisComp", "time", expression);
+    container.addEventListener(ev_type, ev => event_handler(ev, expression_function));
+}
+
+
+

Interlude: Writing a Small Wrapper

+

Follows a JavaScript class that sets everything we've seen until now +in a self-contained object.

+
class LottieInteractionPlayer
+{
+    constructor(container, custom_options={})
+    {
+        if ( typeof container == "string" )
+            this.container = document.getElementById(container);
+        else
+            this.container = container;
+
+        this.anim = null;
+
+        this.custom_options = custom_options;
+
+        // needed by keyup/down
+        if ( !container.hasAttribute("tabindex") )
+            container.setAttribute("tabindex", "0");
+
+        this.handlers = {};
+
+        this._container_event_listener = this.container_event.bind(this);
+    }
+
+    // Deep copy lottie JSON
+    lottie_clone(json)
+    {
+        return JSON.parse(JSON.stringify(json));
+    }
+
+    load(lottie, resize = true)
+    {
+        // Options
+        var options = {
+            container: this.container,
+            renderer: 'svg',
+            loop: true,
+            autoplay: true,
+            // Clone because the player modifies the passed object
+            animationData = this.lottie_clone(lottie);
+            ...this.custom_options,
+        };
+
+        if ( resize )
+        {
+            this.container.style.width = lottie.w + "px";
+            this.container.style.height = lottie.h + "px";
+        }
+
+        // Clean up
+        this.clear();
+
+        // Setup handlers
+        this.handlers = {};
+        if ( lottie.events )
+        {
+            for ( var [name, func] of Object.entries(lottie.events) )
+            {
+                this.handlers[name] = this.expression_to_event_handler(func);
+                this.container.addEventListener(name, this._container_event_listener);
+            }
+        }
+
+        // Create lottie player
+        this.anim = bodymovin.loadAnimation(options);
+    }
+
+    // Destroy the animation
+    clear()
+    {
+        if ( this.anim != null )
+        {
+            try {
+                this.anim.destroy();
+                this.anim = null;
+            } catch ( e ) {}
+        }
+
+        for ( let name of Object.keys(this.handlers) )
+            this.container.removeEventListener(name, this._container_event_listener);
+    }
+
+    // Get the expression `thisComp` global
+    get thisComp()
+    {
+        return this.anim.renderer.compInterface;
+    }
+
+    // Get the expression `time` global
+    get time()
+    {
+        return this.anim.renderer.renderedFrame / this.anim.renderer.globalData.frameRate;
+    }
+
+    // Get an expression layer
+    layer(name)
+    {
+        return this.thisComp(name);
+    }
+
+    // Handles an event from the container element
+    container_event(ev)
+    {
+        this.prepare_lottie_event(ev);
+
+        if ( this.handlers[ev.type] )
+            this.handle_lottie_event(ev, this.handlers[ev.type]);
+    }
+
+    // Adds useful attributes to an event object
+    prepare_lottie_event(ev)
+    {
+        if ( ev.clientX !== undefined )
+        {
+            var rect = this.container.getBoundingClientRect();
+            ev.lottie_x = (ev.clientX - rect.left) / rect.width * this.thisComp.width;
+            ev.lottie_y = (ev.clientY - rect.top) / rect.height * this.thisComp.height;
+        }
+    }
+
+    // Handles an event given a handler
+    handle_lottie_event(ev, handler)
+    {
+        handler(ev, this.thisComp, this.time);
+    }
+
+    // Sets up an event handler
+    expression_to_event_handler(expr)
+    {
+        return Function("event", "thisComp", "time", expr);
+    }
+}
+
+

Level 9: Patching the Renderer

+

So far we've used the vanilla lottie-web player without modifications.

+

This is good for the interactions described until now but for more +advanced stuff we need to patch the player.

+

The code in this level assumes you have a wrapper class similar to the one +described in the interlude.

+

Why

+

Follows a description of some use cases that don't work with the current approach.

+

Initializing Values

+

So far we've initialized custom layer attributes in the expressions using them.

+

We started by checking if time is 0:

+
// Initialize everything at the start
+if ( time == 0 )
+{
+    thisLayer.my_value = size[0] / 2;
+    thisLayer.speed = 60;
+    thisLayer.direction = 1;
+    thisLayer.prev_time = 0;
+}
+
+

Since that isn't always reliable, we moved on to checking if the attributes +are undefined:

+
// Initialization
+if ( thisLayer.px === undefined )
+{
+    thisLayer.px = thisComp.width / 2;
+    thisLayer.py = thisComp.height / 2;
+}
+
+

While this works, it's a bit annoying because you don't know if you can +access another layer's custom attributes on frame 0, so it would be nice +to have an event for this:

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "events": {
+        "load": "thisComp('mylayer').value = 123;"
+    }
+}
+
+

We have the options of the DOMLoaded event from bodymovin:

+
    load(lottie, resize = true)
+    {
+        // (omitted the part of the code that's the same as before)
+
+        // Create lottie player
+        this.anim = bodymovin.loadAnimation(options);
+
+        this.anim.addEventListener("DOMLoaded", this._lottie_loaded_event.bind(this));
+    }
+
+    _lottie_loaded_event()
+    {
+        // Create a dummy event object and invoke the
+        this.container.dispatchEvent(new Event("load"), {});
+    }
+
+

The issue with this is such event can only be fired after the first +frame has been renderer (and expressions have been evaluated at least once).

+

DOM Events from Layers

+

Until now the event handling has been done on the container element. +Since all the layers result in DOM elements, it would be nice to +be able to listen to events from those elements and handle them based +on expressions defined on each layer.

+
{
+    "ty": 4,
+    "nm": "My layer",
+    "ip": 0,
+    "op": 60,
+    "st": 0,
+    "ks": {},
+    "shapes": [],
+    "events": {
+        "click": "thisLayer.clicked = true;"
+    }
+}
+
+

To do this we need a way of mapping the layer in the JSON to the +DOM element and the value for the expression thisLayer.

+

All this information is within the lottie-web SVG renderer but we need +to find a way of accessing it.

+

The first step is to allow a layer object to be passed to the events:

+
    // Handles an event from the container element
+    container_event(ev)
+    {
+        this.prepare_lottie_event(ev);
+
+        if ( this.handlers[ev.type] )
+            this.handle_lottie_event(ev, this.handlers[ev.type], null);
+    }
+
+    // Handles an event given a handler
+    handle_lottie_event(ev, handler, layer)
+    {
+        handler(ev, this.thisComp, this.time, layer);
+    }
+
+    // Sets up an event handler
+    expression_to_event_handler(expr)
+    {
+        return Function("event", "thisComp", "time", "thisLayer", expr);
+    }
+
+

How

+

The gist of it is we need to path the renderer object and inject our +code in some of its methods. Luckily we can do this on the fly:

+
    load(lottie, resize = true)
+    {
+        // (omitted the part of the code that's the same as before)
+
+        // Create lottie player
+        this.anim = bodymovin.loadAnimation(options);
+
+        this._patch_renderer();
+    }
+
+
+    _patch_renderer()
+    {
+        // We patch initItems to trigger an event before any expression is evaluated:
+        var old_init = this.anim.renderer.initItems.bind(this.anim.renderer);
+        var post_init = this._lottie_load_event.bind(this)
+        this.anim.renderer.initItems = function(){
+            old_init();
+            post_init();
+        };
+
+        // We patch createItem to add event listener.
+        // It takes the JSON layer as input and returns the renderer later object
+        this.layer_elements = [];
+        var old_create = this.anim.renderer.createItem.bind(this.anim.renderer);
+        this.anim.renderer.createItem = (function(layer){
+            var item = old_create(layer);
+            this._create_item_event(layer, item);
+            return item;
+        }).bind(this);
+    }
+
+    _lottie_load_event()
+    {
+        let ev = new Event("load", {});
+        this.container.dispatchEvent(ev);
+        for ( let layer of this.layer_elements )
+            layer.dispatchEvent(ev);
+    }
+
+    _create_item_event(lottie, item)
+    {
+        // lottie is the JSON layer
+        // item.layerElement is the DOM element for this layer
+        // item.layerInterface is the expression thisLayer object
+        if ( !lottie.events )
+            return;
+
+        // Create a dummy element for Null layers and the like,
+        // it makes it easier to listen for `load` events
+        let element = item.layerElement ?? document.createElement("div");
+
+        // Keep track of layer elements so they can have the `load` event too
+        this.layer_elements.push(element);
+
+        for ( let [name, func] of Object.entries(lottie.events) )
+        {
+            let handler = this.expression_to_event_handler(func);
+            function listener(ev)
+            {
+                this.prepare_lottie_event(ev);
+                this.handle_lottie_event(ev, handler, item.layerInterface);
+            }
+            element.addEventListener(name, listener.bind(this));
+        }
+    }
+
+

Now that the renderer has been patched can we be assured the patching is +done before the functions we are patching have been called?

+

The short answer is No, but we can have a look at how we can achieve this.

+

Abusing Font Loading

+

When a lottie has external fonts, the lottie-web player waits for every +font to be loaded before initializing the renderer. Which means when you +have text layers, the code above works perfectly.

+

This is nice but not all lotties need text so we'll need something better.

+

Deferring Animation Load

+

The trick is to not pass the lottie JSON to lottie-web until after +we've patched the renderer. This is easy enough because if you call +bodymovin.loadAnimation without path or animationData everything +will be initialized (including the renderer) and only the JSON loading +step is missing.

+

We can use this to patch the renderer before loading the animation:

+
    load(lottie, resize = true)
+    {
+        // Options
+        var options = {
+            container: this.container,
+            renderer: 'svg',
+            loop: true,
+            autoplay: true,
+            ...this.custom_options,
+            // Note that animationData is deferred
+        };
+
+        if ( resize )
+        {
+            this.container.style.width = lottie.w + "px";
+            this.container.style.height = lottie.h + "px";
+        }
+
+        // Clean up
+        this.clear();
+
+        // Setup handlers
+        this.handlers = {};
+        if ( lottie.events )
+        {
+            for ( var [name, func] of Object.entries(lottie.events) )
+            {
+                this.handlers[name] = this.expression_to_event_handler(func);
+                this.container.addEventListener(name, this._container_event_listener);
+            }
+        }
+
+        // Create lottie player
+        this.anim = bodymovin.loadAnimation(options);
+
+        this._patch_renderer();
+
+        this.anim.addEventListener("DOMLoaded", this._lottie_loaded_event.bind(this));
+
+        // Clone because the player modifies the passed object
+        var animation_data = this.lottie_clone(lottie);
+
+        // Load animation separately so we can patch the renderer
+        this.anim.setupAnimation(animation_data);
+    }
+
+

Note that anim.setupAnimation is available from lottie-web version +5.8.0. If you have earlier versions, you should call anim.configAnimation +instead.

+

Triggering new events

+

We know how to make the lottie react to DOM events, but what if we want +to make the DOM react to events triggered from the lottie?

+

We can use the patching setup just discussed to also add events on the +other direction, the only thing we need is adding a method to thisComp, +so it's invokable from the expressions and make it trigger DOM events.

+

The trick is to patch thisComp in the right place, fortunately we've +already done the bulk of the work so we just need to add some more code +when the animation has been loaded:

+
    _lottie_load_event()
+    {
+        let ev = new Event("load", {});
+        this.container.dispatchEvent(ev);
+        for ( let layer of this.layer_elements )
+            layer.dispatchEvent(ev);
+
+        // We add a method for triggering events from the lottie
+        this.thisComp.trigger_event = (function(type, detail){
+            this.container.dispatchEvent(new CustomEvent("lottie." + type, {detail}));
+        }).bind(this);
+    }
+
+

Then you can add event listeners to the element containing the lottie animation.

+

Resulting Wrapper

+

Here's the same wrapper class as described earlier, but with patching +code applied to support the load event and layer events.

+
class LottieInteractionPlayer
+{
+    constructor(container, custom_options={})
+    {
+        if ( typeof container == "string" )
+            this.container = document.getElementById(container);
+        else
+            this.container = container;
+
+        this.anim = null;
+
+        this.custom_options = custom_options;
+
+        // needed by keyup/down
+        if ( !container.hasAttribute("tabindex") )
+            container.setAttribute("tabindex", "0");
+
+        this.handlers = {};
+
+        this._container_event_listener = this.container_event.bind(this);
+    }
+
+    // Deep copy lottie JSON
+    lottie_clone(json)
+    {
+        return JSON.parse(JSON.stringify(json));
+    }
+
+    load(lottie, resize = true)
+    {
+        // Options
+        var options = {
+            container: this.container,
+            renderer: 'svg',
+            loop: true,
+            autoplay: true,
+            ...this.custom_options,
+            // Note that animationData is deferred
+        };
+
+        if ( resize )
+        {
+            this.container.style.width = lottie.w + "px";
+            this.container.style.height = lottie.h + "px";
+        }
+
+        // Clean up
+        this.clear();
+
+        // Setup handlers
+        this.handlers = {};
+        if ( lottie.events )
+        {
+            for ( var [name, func] of Object.entries(lottie.events) )
+            {
+                this.handlers[name] = this.expression_to_event_handler(func);
+                this.container.addEventListener(name, this._container_event_listener);
+            }
+        }
+
+        // Create lottie player
+        this.anim = bodymovin.loadAnimation(options);
+
+        this._patch_renderer();
+
+        // Clone because the player modifies the passed object
+        var animation_data = this.lottie_clone(lottie);
+
+        // Load animation separately so we can patch the renderer
+        this.anim.setupAnimation(animation_data);
+    }
+
+    _patch_renderer()
+    {
+        // We patch initItems to trigger an event before any expression is evaluated:
+        var old_init = this.anim.renderer.initItems.bind(this.anim.renderer);
+        var post_init = this._lottie_load_event.bind(this)
+        this.anim.renderer.initItems = function(){
+            old_init();
+            post_init();
+        };
+
+        // We patch createItem to add event listener.
+        // It takes the JSON layer as input and returns the renderer later object
+        this.layer_elements = [];
+        var old_create = this.anim.renderer.createItem.bind(this.anim.renderer);
+        this.anim.renderer.createItem = (function(layer){
+            var item = old_create(layer);
+            this._create_item_event(layer, item);
+            return item;
+        }).bind(this);
+    }
+
+    _create_item_event(lottie, item)
+    {
+        // lottie is the JSON layer
+        // item.layerElement is the DOM element for this layer
+        // item.layerInterface is the expression thisLayer object
+        if ( !lottie.events )
+            return;
+
+        // Create a dummy element for Null layers and the like,
+        // it makes it easier to listen for `load` events
+        let element = item.layerElement ?? document.createElement("div");
+
+        // Keep track of layer elements so they can have the `load` event too
+        this.layer_elements.push(element);
+
+        for ( let [name, func] of Object.entries(lottie.events) )
+        {
+            let handler = this.expression_to_event_handler(func);
+            function listener(ev)
+            {
+                this.prepare_lottie_event(ev);
+                this.handle_lottie_event(ev, handler, item.layerInterface);
+            }
+            element.addEventListener(name, listener.bind(this));
+        }
+    }
+
+    _lottie_load_event()
+    {
+        let ev = new Event("load", {});
+        this.container.dispatchEvent(ev);
+        for ( let layer of this.layer_elements )
+            layer.dispatchEvent(ev);
+
+        // We add a method for triggering events from the lottie
+        this.thisComp.trigger_event = (function(type, detail){
+            this.container.dispatchEvent(new CustomEvent("lottie." + type, {detail}));
+        }).bind(this);
+    }
+
+    // Destroy the animation
+    clear()
+    {
+        if ( this.anim != null )
+        {
+            try {
+                this.anim.destroy();
+                this.anim = null;
+            } catch ( e ) {}
+        }
+
+        for ( let name of Object.keys(this.handlers) )
+            this.container.removeEventListener(name, this._container_event_listener);
+    }
+
+    // Get the expression `thisComp` global
+    get thisComp()
+    {
+        return this.anim.renderer.compInterface;
+    }
+
+    // Get the expression `time` global
+    get time()
+    {
+        return this.anim.renderer.renderedFrame / this.anim.renderer.globalData.frameRate;
+    }
+
+    // Get an expression layer
+    layer(name)
+    {
+        return this.thisComp(name);
+    }
+
+    // Handles an event from the container element
+    container_event(ev)
+    {
+        this.prepare_lottie_event(ev);
+
+        if ( this.handlers[ev.type] )
+            this.handle_lottie_event(ev, this.handlers[ev.type], null);
+    }
+
+    // Adds useful attributes to an event object
+    prepare_lottie_event(ev)
+    {
+        if ( ev.clientX !== undefined )
+        {
+            var rect = this.container.getBoundingClientRect();
+            ev.lottie_x = (ev.clientX - rect.left) / rect.width * this.thisComp.width;
+            ev.lottie_y = (ev.clientY - rect.top) / rect.height * this.thisComp.height;
+        }
+    }
+
+    // Handles an event given a handler
+    handle_lottie_event(ev, handler, layer)
+    {
+        handler(ev, this.thisComp, this.time, layer);
+    }
+
+    // Sets up an event handler
+    expression_to_event_handler(expr)
+    {
+        return Function("event", "thisComp", "time", "thisLayer", expr);
+    }
+}
+
+

Animation or Interaction

+

It's possible to use the custom load to detect whether the lottie +is being played in an environment that supports the custom events.

+

The following example is similar to the click example from level 7 +but when a player doesn't have interaction support, the star moves +around on its own.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "events": {
+        "click": "var star = thisComp('star'); star.px = event.lottie_x; star.py = event.lottie_y;",
+        "load": "thisComp('star').interactive = true;"
+    },
+    "layers": [
+        {
+            "ty": 4,
+            "nm": "star",
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "ks": {
+                "p": {"a": 0, "k": [0, 0], "x": `
+// Initialization
+if ( thisLayer.px === undefined )
+{
+    thisLayer.px = thisComp.width / 2;
+    thisLayer.py = thisComp.height / 2;
+
+    if ( !thisLayer.interactive )
+    {
+        thisLayer.dx = 1;
+        thisLayer.dy = 1;
+        thisLayer.prev_time = 0;
+    }
+}
+
+if ( !thisLayer.interactive )
+{
+    if ( time < thisLayer.prev_time )
+        thisLayer.prev_time = time;
+    var dt = time - thisLayer.prev_time;
+    thisLayer.prev_time = time;
+
+    thisLayer.px += thisLayer.dx * dt * 100;
+    thisLayer.py += thisLayer.dy * dt * 120;
+
+    var radius = thisLayer.content(1).outerRadius;
+    if ( thisLayer.px < radius )
+        thisLayer.dx = 1;
+    else if ( thisLayer.px > thisComp.width - radius )
+        thisLayer.dx = -1;
+    if ( thisLayer.py < radius )
+        thisLayer.dy = 1;
+    else if ( thisLayer.py > thisComp.height - radius )
+        thisLayer.dy = -1;
+
+}
+
+// Set value
+var $bm_rt = [thisLayer.px, thisLayer.py];
+                `}},
+            "shapes": [
+                {
+                    "ty": "sr",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "or": {"a": 0, "k": 70},
+                    "ir": {"a": 0, "k": 40},
+                    "r": {"a": 0, "k": 0},
+                    "pt": {"a": 0, "k": 5},
+                    "sy": 1,
+                    "os": {"a": 0, "k": 0},
+                    "is": {"a": 0, "k": 0}
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 100},
+                    "c": {
+                        "a": 0,
+                        "k": [1, 1, 0.3],
+                    }
+                }
+            ]
+        }
+    ]
+}
+
<div id="level9_parent">
+    <div id="level9_not_interactive"></div>
+    <div id="level9_interactive"></div>
+</div>
+
#level9_parent {
+    display: flex;
+}
+#level9_interactive, #level9_not_interactive {
+    border: 1px solid #ccc;
+    width: 50%;
+    box-sizing: border-box;
+}
+
var options = {
+    container: document.getElementById("level9_not_interactive"),
+    renderer: "svg",
+    loop: true,
+    autoplay: true,
+    animationData: json,
+};
+var anim = bodymovin.loadAnimation(options);
+
+var player = new LottieInteractionPlayer(document.getElementById("level9_interactive"));
+player.load(json, false);
+
+
+
+
+
+

Lottie Button Example

+

This example uses everything we discussed so far.

+

A quick note: to avoid clicks going to the wrong layer we need to define +some CSS that gets rid of pointer events for layers we don't want to click.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "fonts": {"list":[
+        {
+            "ascent": 72,
+            "fFamily": "Roboto",
+            "fName": "Roboto Regular",
+            "fStyle": "Regular",
+            "fPath": "https://fonts.googleapis.com/css2?family=Roboto&display=swap",
+            "origin": 1,
+        }
+    ]},
+    "layers": [
+        {
+            "ty": 5,
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "parent": 1,
+            "cl": "no-mouse",
+            "ks": {
+                "p": {"a": 0, "k": [0, 25]},
+            },
+            "t": {
+                "a": [],
+                "d": {
+                    "x": "var $bm_rt = 'Clicks: ' + thisComp('button').clicks;",
+                    "k": [
+                        {
+                            "s": {
+                                "f": "Roboto Regular",
+                                "fc": [0, 0, 0],
+                                "s": 70,
+                                "t": "",
+                                "j": 2,
+                            },
+                            "t": 0
+                        }
+                    ]
+                },
+                "m": {
+                    "a": {"a": 0, "k": [0,0]},
+                    "g": 3
+                },
+                "p": {}
+            }
+        },
+        {
+            "ty": 4,
+            "nm": "button",
+            "ip": 0,
+            "op": 60,
+            "st": 0,
+            "ind": 1,
+            "cl": "lottie-button",
+            "events": {
+                "load": "thisLayer.clicks = 0;",
+                "click": "thisLayer.clicks += 1; thisComp.trigger_event('click', {clicks: thisLayer.clicks});",
+                "mouseenter": "thisLayer.highlighted = true;",
+                "mouseleave": "thisLayer.highlighted = false;"
+            },
+            "ks": {
+                "p": {"a": 0, "k": [256, 256]},
+                "s": {
+                    "a": 0,
+                    "k": [100, 100],
+                    "x": "var sz = thisLayer.highlighted ? 120 : 100; var $bm_rt = [sz, sz];"
+                }
+            },
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "p": {"a": 0, "k": [0, 0]},
+                    "s": {"a": 0, "k": [350, 90]},
+                    "r": {"a": 0, "k": 3},
+                },
+                {
+                    "ty": "st",
+                    "o": {"a": 0, "k": 100},
+                    "c": {"a": 0, "k": [0, 1, 0]},
+                    "w": {"a": 0, "k": 1},
+                },
+                {
+                    "ty": "fl",
+                    "o": {"a": 0, "k": 50, "x": "var $bm_rt = thisLayer.highlighted ? 70 : 30;"},
+                    "c": {"a": 0, "k": [0.4, 1, 0.4]}
+                }
+            ]
+        }
+    ]
+}
+
var container = document.getElementById("level9_button");
+var player = new LottieInteractionPlayer(container);
+player.load(json);
+container.addEventListener("lottie.click", ev =>
+    document.getElementById("level9_outer").innerText = `Lottie clicked ${ev.detail.clicks} times`
+);
+
<div id="level9_button"></div>
+<div id="level9_outer">Button not clicked</div>
+
.no-mouse {
+    pointer-events: none;
+}
+.lottie-button {
+    cursor: pointer;
+}
+
+
Button not clicked
+
+

3D

+

Everything discussed so far was for the lottie-web svg renderer +but all the patching works with the html renderer as well.

+

The html renderer supports 3D layers so we can make an interactive +3D scene with little effort.

+

The main caveat is that you need to set position: relative on the +container element.

+

On the example below you can click to capture the mouse then have +first-person controls.

+
{
+    "v": "5.9.1",
+    "ip": 0,
+    "op": 180,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "fonts": {
+        "list": []
+    },
+    "assets": [],
+    "layers": [
+        {
+            "nm": "Camera",
+            "ty": 13,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "sr": 1,
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        -10
+                    ]
+                },
+                "rx": {
+                    "a": 0,
+                    "k": 0
+                },
+                "ry": {
+                    "a": 0,
+                    "k": 0
+                },
+                "rz": {
+                    "a": 0,
+                    "k": 0
+                },
+                "or": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ]
+                }
+            },
+            "pe": {
+                "a": 0,
+                "k": 256
+            },
+            "ddd": 1
+        },
+        {
+            "nm": "Move Parent",
+            "ty": 3,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "sr": 1,
+            "ks": {
+                "a": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ],
+                    "x": "var dt = thisComp.time_delta(thisLayer, time);\n\n            if ( thisComp.mouse_dx )\n            {\n                thisComp.char_angle -= dt * thisComp.mouse_dx / 8 * Math.PI;\n                thisComp.mouse_dx  = 0;\n            }\n\n            if ( thisComp.mouse_dy )\n            {\n                thisComp.look_angle += dt * thisComp.mouse_dy / 8 * Math.PI;\n                thisComp.mouse_dy  = 0;\n            }\n\n\n            var left = thisComp.keys_pressed.ArrowLeft || thisComp.keys_pressed.a;\n            var right = thisComp.keys_pressed.ArrowRight || thisComp.keys_pressed.d;\n            var dx = 0;\n            if ( left && right )\n                dx = 0;\n            else if ( left )\n                dx = -1;\n            else if ( right )\n                dx = 1;\n\n            var up = thisComp.keys_pressed.ArrowUp || thisComp.keys_pressed.w;\n            var down = thisComp.keys_pressed.ArrowDown || thisComp.keys_pressed.s;\n            var dz = 0;\n            if ( up && down )\n                dz = 0;\n            else if ( up )\n                dz = 1;\n            else if ( down )\n                dz = -1;\n\n            thisLayer.char_x += dz * dt * -200 * Math.sin(thisComp.char_angle);\n            thisLayer.char_z += dz * dt * 200 * Math.cos(thisComp.char_angle);\n\n            thisLayer.char_x += dx * dt * -200 * Math.sin(thisComp.char_angle - Math.PI / 2);\n            thisLayer.char_z += dx * dt * 200 * Math.cos(thisComp.char_angle - Math.PI / 2);\n\n            var $bm_rt = [thisLayer.char_x, thisLayer.char_y, thisLayer.char_z];\n        \n/**/"
+                },
+                "rx": {
+                    "a": 0,
+                    "k": 0
+                },
+                "ry": {
+                    "a": 0,
+                    "k": 0
+                },
+                "rz": {
+                    "a": 0,
+                    "k": 0
+                },
+                "or": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ],
+                    "x": "var $bm_rt = [thisComp.look_angle * 180 / Math.PI, thisComp.char_angle * 180 / Math.PI, 0];\n        \n/**/"
+                }
+            },
+            "ind": 1,
+            "ddd": 1,
+            "events": {
+                "load": "thisLayer.char_x = 0;\n            thisLayer.char_z = 0;\n            thisLayer.char_y = 0;\n        \n/**/"
+            }
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "sr": 1,
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        200
+                    ]
+                },
+                "rx": {
+                    "a": 0,
+                    "k": 0
+                },
+                "ry": {
+                    "a": 0,
+                    "k": 0
+                },
+                "rz": {
+                    "a": 0,
+                    "k": 0
+                },
+                "or": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ]
+                }
+            },
+            "ddd": 1,
+            "parent": 1,
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "s": {
+                        "a": 0,
+                        "k": [
+                            200,
+                            200
+                        ]
+                    },
+                    "p": {
+                        "a": 0,
+                        "k": [
+                            0,
+                            0
+                        ]
+                    },
+                    "r": {
+                        "a": 0,
+                        "k": 0
+                    }
+                },
+                {
+                    "ty": "fl",
+                    "c": {
+                        "a": 0,
+                        "k": [
+                            0.5,
+                            0.5,
+                            1
+                        ]
+                    },
+                    "o": {
+                        "a": 0,
+                        "k": 100
+                    }
+                }
+            ]
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "sr": 1,
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        -200
+                    ]
+                },
+                "rx": {
+                    "a": 0,
+                    "k": 0
+                },
+                "ry": {
+                    "a": 0,
+                    "k": 0
+                },
+                "rz": {
+                    "a": 0,
+                    "k": 0
+                },
+                "or": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ]
+                }
+            },
+            "ddd": 1,
+            "parent": 1,
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "s": {
+                        "a": 0,
+                        "k": [
+                            200,
+                            200
+                        ]
+                    },
+                    "p": {
+                        "a": 0,
+                        "k": [
+                            0,
+                            0
+                        ]
+                    },
+                    "r": {
+                        "a": 0,
+                        "k": 0
+                    }
+                },
+                {
+                    "ty": "fl",
+                    "c": {
+                        "a": 0,
+                        "k": [
+                            0.5,
+                            0.5,
+                            0
+                        ]
+                    },
+                    "o": {
+                        "a": 0,
+                        "k": 100
+                    }
+                }
+            ]
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "sr": 1,
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [
+                        200,
+                        0,
+                        0
+                    ]
+                },
+                "rx": {
+                    "a": 0,
+                    "k": 0
+                },
+                "ry": {
+                    "a": 0,
+                    "k": 90
+                },
+                "rz": {
+                    "a": 0,
+                    "k": 0
+                },
+                "or": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ]
+                }
+            },
+            "ddd": 1,
+            "parent": 1,
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "s": {
+                        "a": 0,
+                        "k": [
+                            200,
+                            200
+                        ]
+                    },
+                    "p": {
+                        "a": 0,
+                        "k": [
+                            0,
+                            0
+                        ]
+                    },
+                    "r": {
+                        "a": 0,
+                        "k": 0
+                    }
+                },
+                {
+                    "ty": "fl",
+                    "c": {
+                        "a": 0,
+                        "k": [
+                            1,
+                            0.5,
+                            0.5
+                        ]
+                    },
+                    "o": {
+                        "a": 0,
+                        "k": 100
+                    }
+                }
+            ]
+        },
+        {
+            "ty": 4,
+            "ip": 0,
+            "op": 180,
+            "st": 0,
+            "sr": 1,
+            "ks": {
+                "p": {
+                    "a": 0,
+                    "k": [
+                        -200,
+                        0,
+                        0
+                    ]
+                },
+                "rx": {
+                    "a": 0,
+                    "k": 0
+                },
+                "ry": {
+                    "a": 0,
+                    "k": 90
+                },
+                "rz": {
+                    "a": 0,
+                    "k": 0
+                },
+                "or": {
+                    "a": 0,
+                    "k": [
+                        0,
+                        0,
+                        0
+                    ]
+                }
+            },
+            "ddd": 1,
+            "parent": 1,
+            "shapes": [
+                {
+                    "ty": "rc",
+                    "s": {
+                        "a": 0,
+                        "k": [
+                            200,
+                            200
+                        ]
+                    },
+                    "p": {
+                        "a": 0,
+                        "k": [
+                            0,
+                            0
+                        ]
+                    },
+                    "r": {
+                        "a": 0,
+                        "k": 0
+                    }
+                },
+                {
+                    "ty": "fl",
+                    "c": {
+                        "a": 0,
+                        "k": [
+                            0,
+                            0.5,
+                            0.5
+                        ]
+                    },
+                    "o": {
+                        "a": 0,
+                        "k": 100
+                    }
+                }
+            ]
+        }
+    ],
+    "events": {
+        "keydown": "thisComp.keys_pressed[event.key] = true;\n\n        if ( event.key != \"F5\" )\n            event.preventDefault();\n    \n/**/",
+        "keyup": "thisComp.keys_pressed[event.key] = false;\n\n        if ( event.key != \"F5\" )\n            event.preventDefault();\n    \n/**/",
+        "load": "thisComp.keys_pressed = {};\n        thisComp.mouse_dx = 0;\n        thisComp.mouse_dy = 0;\n        thisComp.char_angle = 0;\n        thisComp.look_angle = 0;\n        thisComp.time_delta = function (thisLayer, time) {\n            if ( thisLayer.last_time === undefined || time < thisLayer.last_time )\n            {\n                thisLayer.last_time = time;\n                return 0;\n            }\n\n            var dt = time - thisLayer.last_time;\n            thisLayer.last_time = time;\n            return dt;\n        };\n    \n/**/",
+        "mouseenter": "thisComp.mouse_old_x = thisComp.mouse_x = event.lottie_x;\n        thisComp.mouse_old_y = thisComp.mouse_y = event.lottie_x;\n    \n/**/",
+        "mouseleave": "thisComp.mouse_old_x = thisComp.mouse_x = event.lottie_x;\n        thisComp.mouse_old_y = thisComp.mouse_y = event.lottie_x;\n    \n/**/",
+        "mousemove": "thisComp.mouse_dx += event.movementX;\n        thisComp.mouse_dy += event.movementY;\n    \n/**/"
+    },
+    "ddd": 1
+}
+
var container = document.getElementById("level9_3d");
+var player = new LottieInteractionPlayer(container, {renderer: "html"});
+player.load(json);
+
<div id="level9_3d" onclick="this.requestPointerLock();"></div>
+
#level9_3d {
+    position: relative;
+}
+
+
+
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aep/index.html b/aep/index.html new file mode 100644 index 00000000..44a3efe8 --- /dev/null +++ b/aep/index.html @@ -0,0 +1,5984 @@ + + + + + + + + + + + + + + Parsing AEP Files - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Parsing AEP Files

+

AfterEffects Project files are the proprietary file format used by Adobe AfterEffects.

+

It's a binary format based on the RIFX container format.

+

The structure resembles that of a Lottie JSON exported from AE.

+

RIFF

+

A RIFF is composed of "chunks" with the following format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldSizeDescription
Header4ASCII name describing the type of the chunk
Size4uint32 size of the data section
DataSizeData within the chunk
+

RIFX is an extension of the RIFF format, the difference being RIFX +uses big-endian notation for integers.

+

A RIFF file will be structured in the same way as a chunk:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldSizeDescription
Header4RIFF or RIFX
Size4uint32 size of the chunk
Format4Format Identifier
Chunks*Rest of the chunks
+

AEP-Specific Parsing

+

It should always be RIFX format (big endian). The format identifier +for AEP is Egg!.

+

When parsing the RIFF structure, keep in mind the following chunks +will contain other chunks:

+ +

And that LIST btdk contains data in a different format, and +it should not be parsed as a RIFF LIST.

+

At the end of the RIFF data, the AEP file has some XML-encoded metadata.

+

Basic Types

+

In the chunk data descriptions, the types described below will be used +to show how to interpret the raw binary data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeSizeDescription
id4ASCII-encoded chunk identifier
uint162Unsigned integer
uint324Unsigned integer
sint162Twos-complement signed integer
float324IEEE float
float648IEEE float
string*Text, usually utf-8 encoded
string0*NUL terminated string, note that you might find junk data after the NUL (This can be caused by renaming something to a shorter name)
bytes*Unformatted / unknown data
+

Time

+

Time values are stored as uint16. they are scaled by a factor you can find in cdta.

+

To get the actual value in frames you need to do the following:

+
time_frames = time_value / cdta.time_scale
+
+

Additionally, layers specify a start time, which shifts all the time values by a fixed amount.

+

If you are within a layer the expression looks like this:

+
time_frames = (time_value + ldta.start_time) / (cdta.time_scale)
+
+

Flags

+

Flags is byte data, that will be specified using two integers: byte and bit index.

+

You'll get the value of the flag you'll need to do the following:

+
flag = (flags[byte] & (1 << bit)) != 0
+
+

The index of the byte here is in file order so a byte of 0 is the most significant byte.

+

AfterEffects Logic

+

This section assumes the file has already been parsed into RIFF chunks.

+

Objects described here will have a nested list showing which chunks are +used to represent them, you can click on the link pointing to the chunk +details to get the data layout within that chunk.

+

File Structure

+ +

Folder Item

+ +

idta will cointain the ID of the item (referenced by layers) +and the item type.

+

The following sections descript each type of item in detail

+

Folders

+

idta type 1. These contain additional items inside them.

+ +

Compositions

+

idta has type of 4. You need to know which composition to extract as +a lottie corresponds to a specific comp (with other compositions showing +as assets for precomps).

+

Structure:

+ +

Each layer will show as a LIST Layr in the LIST Item.

+

The composition will also have other type of layer LISTs:

+ +

If the comp uses essential graphics, it will have the appropriate LISTs as well.

+

Assets

+

idta type 7. These can have different kinds of contents.

+

Look for sspc to get the size for visual assets.

+

The type of asset is defined in the first 4 bytes of opti.

+
Solids
+

For some the Item has an Utf8 but it seems to always be empty +need to find the name from opti.

+ +
Files
+ +

The Uft8 in Item only has a value if the user has set an explicit value for the name.

+

The file path is in alas, parse it as JSON and get fullpath.

+

the first 4 bytes of opti will change based on the file format.

+

Layers

+ +

When parsing layer transforms, keep in mind the default position is the center of the comp. +For shape layers, the default anchor is [0, 0]; +for precomp layers the default anchor is the center of the comp (same as position).

+

Asset Layer

+

Layer type 0.

+

(Also known as AVLayer in AE) They have a non-zero Source ID in ldta.

+

Precomp, image, and similar layers will point to an appropriate asset.

+

Several layer types point to a solid asset, you need to check the layer +attributes to distinguish between them:

+
    +
  • Solid layers
  • +
  • Null layers
  • +
  • Adjustment layers
  • +
+

Light Layer

+

Layer type 1.

+

For light settings look for the match name ADBE Light Options Group.

+

Camera Layer

+

Layer type 2.

+

For camera settings look for the match name ADBE Camera Options Group.

+

Text Layer

+

Layer type 3.

+

For text contents look for the match name ADBE Text Properties.

+

Shape Layer

+

Layer type 4.

+

For shapes look for the match name ADBE Root Vectors Group.

+

Property Groups

+

Most objects are described as a property groups.

+

These have the following structure:

+
    +
  • LIST tdgp: Property group
      +
    • tdsb: Flags
    • +
    • tdsn > Utf8: Name
    • +
    • ... (properties)
    • +
    • tdmn: ADBE Group End (marks the end of the group)
    • +
    +
  • +
+

Then follows a list of properties, all introduced by their +match name (tdmn).

+

After a match name, you'll find the data for the property, which might +be an actual propert (see the section below), other groups, or layer effects.

+

This structure is used both for objects (that have a fixed set of properties) +and groups/collections whose contents might vary.

+

For objects with fixed properties you will not find duplicate match names +but you might find duplicates within collections.

+

Properties

+

Properties, like objects are introduced by their match name, the chunks +following that depends on the type of property.

+

The core of a property is defined in LIST tdbs with the following structure:

+
    +
  • LIST tdbs: Property definition
      +
    • tdb4: Tells you the type, number of components, whether it's animated
    • +
    • cdat: Value (if not animated)
    • +
    • tdsn:
        +
      • Utf8: Human-readable Name
      • +
      +
    • +
    • Utf8: Optional expression
    • +
    • LIST list: Keyframes (if animated)
        +
      • lhd3: Tells you the number of keyframes
      • +
      • ldat: Keyframe data and values
      • +
      +
    • +
    +
  • +
+

For simple properties, with vector or scalar values, you get the structure above.

+

For more complex properties, you get an outer object that contains that data as well +as a list of values. You'll get the value for the keyframes (or the static value) from that list.

+

Color properties are laid out as ARGB floats in [0, 255].

+

Note that the keyframe structure in ldat changes based on the info found in tdb4.

+

Shape

+ +

Gradient Colors

+ +

Orientation

+ +

Marker

+ +

Text Document

+ +

Layer

+

Follows the usual LIST tdbs, check tdb4 for the "Integer" property type.

+ +

Mask Index

+

Follows the usual LIST tdbs, check tdb4 for the "Integer" property type.

+ +

Mask

+ +

Layer Overrides

+
    +
  • LIST OvG2
      +
    • CprC: uint32?
    • +
    +
  • +
+

Layer Source Alternate

+
    +
  • blsv: uint32 Layer index?
  • +
  • blsi: uint32
  • +
+

Chunk naming

+

Most of property related chunks seem to contain the prefix td in their name:

+
    +
  • tdgp: property group
  • +
  • tdsb: property group flags
  • +
  • tdsn: property group name
  • +
  • tdmn: property match name
  • +
  • tdbs: property definition
  • +
  • tdb4: property details
  • +
+

I'm not sure what td stands for my best guess would be "Track Data".

+

For properties with external values, the naming convention generally is XXst for the parent chunk +and XXky for the values (where XX changes depending on the type and its meaning is fairly obvious).

+

I'm not sure what st stands for, ky most likely stands for "keyframes"

+

Expressions

+

Bodymovin modifies expressions +when converting into lottie, if you add expressions but fail to convert them, the animation +might not play properly.

+

Assets

+

Image

+

Defined within LIST Item, it will have idta with type 7.

+

Within that there's a LIST Pin, containing the following:

+

LIST Als2 with alas, which in turn has some JSON. +Inside the JSON you can get fullpath.

+

opti: Contains the asset name.

+

LIST CLRS, the last Utf8 here has some JSON with a base64-encoded color profile.

+

Shapes

+

Stroke Dashes

+

Look for the match name ADBE Vector Stroke Dashes.

+

Inside of it you'll find a bunch of properties with match name +ADBE Vector Stroke Dash n or ADBE Vector Stroke Gap n, where n is +an ineger starting from 1.

+

You will also find a single ADBE Vector Stroke Offset.

+

They are all animatable lengths and fairly straighforward.

+

Note that lottie-web wants a unique "name" for these, and the file doesn't provide this +but you can generate one based on the match name.

+

Transforms

+

Split Position

+

When a position is split the Position attribute is removed and you can get the data from Position_0 and Position_1.

+

For some reason Position_0 and Position_1 are present (with value 0) even when the position is not split.

+

Their tdsb seems to change from 1 (not split) to 3 (split).

+

Effects

+

The effects used in by the file are defined in the top-level chunk LIST EfdG, instanciations of these effects +are present in the layers that use them.

+
    +
  • LIST EfdG: Effect definitions
      +
    • EfDC: Effect definition count (number of definitions)
    • +
    • LIST EfDf: Effect definition (one per effect type used in the document)
        +
      • tdmn: Effect match name
      • +
      • LIST sspc
          +
        • fnam > Utf8: Effect name
        • +
        • LIST parT: Effect parameters
            +
          • parn: Number of parameters
          • +
          • tdmn: Parameter match name
          • +
          • pard: Parameter definition
          • +
          • pdnm: (optional) Parameter control strings
          • +
          • You get tdmn and pard (optionally followed by pdnm for each parameter
          • +
          +
        • +
        • LIST tdgp: Contains the values of the first instance of this effect, can be ignored
        • +
        +
      • +
      +
    • +
    +
  • +
+

Note that the first paramter in an effect should be ignored.

+

The effects in a later are listed under ADBE Effect Parade:

+
    +
  • tdmn: Effect match name, you'll need to find the matching definition
  • +
  • LIST sspc
      +
    • fnam > Utf8: Effect name
    • +
    • LIST parT: You might find this here as well but it isn't consistent. Refer to LIST EfdG for the definition
    • +
    • LIST tdgp: Parameter values, works like any other property list
    • +
    +
  • +
+

Essential Graphics

+

Definition

+

Essential graphics are defined in the following chunks inside the comp's LIST Item:

+ +

They seem to have the same structure and (almost) identical values. But only CIF3 +has data about groups:

+
    +
  • LIST CIF3
      +
    • LIST CpS2
        +
      • CsCt: seems to always have the value 0x1000000.
      • +
      • Utf8: Name (Defaults to Untitled)
      • +
      • Utf8: Locale? (en_US)
      • +
      +
    • +
    • CapS
        +
      • CsCt: seems to always have the value 0x1000000.
      • +
      • CapL: seems to always have the value 0.
      • +
      • Utf8: Name (again, same value as before)
      • +
      +
    • +
    • LIST CCtl: Item (repeated)
    • +
    +
  • +
+

Items have the following common structure

+ +
Comment
+ +
Group
+ +
Property
+
    +
  • CVal: Value
  • +
  • CDef: Default Value
  • +
  • Smin: Slider min value (only for scalar properties)
  • +
  • Smax: Slider max value (only for scalar properties)
  • +
  • CDim: Number of dimenstions (only for vector properties)
  • +
  • LIST StVc: Enum values (only for enum properties)
      +
    • StVS: Count
    • +
    • Utf8: Value name (repeated)
    • +
    +
  • +
  • CprC: 1
  • +
  • LIST CPrp
      +
    • CCId: Composition ID (same as the one in idta).
    • +
    • CLId: Layer ID (same as the one in ldta).
    • +
    • Utf8: JSON-ecoded path.
    • +
    +
  • +
+

The JSON is a dict where the key is a string containing a number and the values are dicts like this:

+
    +
  • index: Index for like shape groups and such, or the value 4294967295 (0xffffffff) is used when there is no index
  • +
  • matchName: Match name as per usual
  • +
+

To find the property, something like this might work:

+
CCId = 15
+CLId = 18
+json_data = {
+    "0": {
+        "index":4294967295,
+        "matchName":"ADBE Root Vectors Group"
+    },
+    "1": {
+        "index":0,
+        "matchName":"ADBE Vector Group"
+    },
+    "2": {
+        "index":4294967295,
+        "matchName":"ADBE Vectors Group"
+    },
+    "3": {
+        "index":2,
+        "matchName":"ADBE Vector Graphic - Fill"
+    },
+    "4": {
+        "index":4294967295,
+        "matchName":"ADBE Vector Fill Opacity"
+    }
+}
+
+property = get_layer(CCId, CLId)
+
+for item in json_data.values():
+    if item["index"] == 0xffffffff:
+        property = property.property(item["matchName"])
+    else:
+        property = property.properties[item["index"]]
+
+

The values in Smin, Smax, CVal, CDef depends on the type, refer to CTyp for their representation.

+

Overrides

+

Defined in the precomp layer under match name ADBE Layer Overrides

+
    +
  • tdmn: ADBE Layer Overrides
  • +
  • LIST OvG2
      +
    • LIST CPrp: (repeated)
        +
      • Utf8: UUID of the essential property
      • +
      +
    • +
    +
  • +
  • LIST tdgp: Property groups with the matching properties defined as usual.
  • +
+

Match Names

+

Follows a list of known match names grouped by object type.

+

For properties that specify a default value, you should assume they have the specified value if they are not present in the +AEP file.

+

Layers

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Root Vectors Group shapes
ADBE Layer Styles styles
ADBE Transform Group ks
ADBE Layer Styles sy
ADBE Extrsn Options Group
ADBE Material Options Group
ADBE Audio Group
ADBE Layer Sets
ADBE Time Remapping tm
ADBE Effect Parade ef
ADBE Marker Markers
ADBE Mask Parade masksProperties
ADBE Plane Options Group
ADBE Data Group
ADBE Layer Overrides Essential graphincs values
ADBE Source Options Group
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Camera Options Group Camera LayerMarks a layer as a camera layer
ADBE Camera Aperture pe
ADBE Camera Zoom
ADBE Camera Focus Distance
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Mask Atom Mask
ADBE Mask Shape pt
ADBE Mask Offset x0
ADBE Mask Feather [0, 0]
ADBE Mask Opacity 0100
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Extrsn Options Group
ADBE Bevel Direction
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Material Options Group
ADBE Appears in Reflections
ADBE Reflection Coefficient
ADBE Glossiness Coefficient
ADBE Fresnel Coefficient
ADBE Transparency Coefficient
ADBE Transp Rolloff
ADBE Index of Refraction
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Source Options Group
ADBE Layer Source Alternate
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Layer Styles
ADBE Blend Options Group
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Blend Options Group
ADBE Adv Blend Group
+

Shapes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Group Group
ADBE Vector Blend Mode bm12
ADBE Vectors Group it
ADBE Vector Transform Group Transform
ADBE Vector Materials Group
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Shape - Rect Rectangle
ADBE Vector Shape Direction d1
ADBE Vector Rect Position p
ADBE Vector Rect Size s
ADBE Vector Rect Roundness r
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Shape - Ellipse Ellipse
ADBE Vector Shape Direction d1
ADBE Vector Ellipse Position p
ADBE Vector Ellipse Size s
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Shape - Star PolyStar
ADBE Vector Shape Direction d1
ADBE Vector Star Type sy1
ADBE Vector Star Points pt3
ADBE Vector Star Position p
ADBE Vector Star Rotation r
ADBE Vector Star Inner Radius ir
ADBE Vector Star Outer Radius or
ADBE Vector Star Inner Roundess is
ADBE Vector Star Outer Roundess os
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Shape - Group Path
ADBE Vector Shape Direction d1
ADBE Vector Shape ks4
+

Shape Styles

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Graphic - Fill Fill
ADBE Vector Blend Mode bm12
ADBE Vector Fill Color c5 [255, 255, 0, 0]
ADBE Vector Fill Opacity o100
ADBE Vector Fill Rule r1 1
ADBE Vector Composite Order if 2, it should be drawn over the previous shape 1
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Graphic - Stroke Stroke
ADBE Vector Blend Mode bm12
ADBE Vector Stroke Color c5 [255, 255, 255, 255, ]
ADBE Vector Stroke Opacity o100
ADBE Vector Stroke Width w2
ADBE Vector Stroke Line Cap lc1 1
ADBE Vector Stroke Line Join lj1 1
ADBE Vector Stroke Miter Limit ml24
ADBE Vector Stroke Dashes d
ADBE Vector Stroke Taper
ADBE Vector Stroke Wave
ADBE Vector Composite Order if 2, it should be drawn over the previous shape 1
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Stroke Taper All properties are percentages in [0, 100]
ADBE Vector Taper Start Length
ADBE Vector Taper End Length
ADBE Vector Taper Start Width
ADBE Vector Taper End Width
ADBE Vector Taper Start Ease
ADBE Vector Taper End Ease
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Stroke Wave
ADBE Vector Taper Wave Amount
ADBE Vector Taper Wave Units 1 for pixels, 2 for cycles
ADBE Vector Taper Wavelength
ADBE Vector Taper Wave Phase
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Stroke Dashes
ADBE Vector Stroke Offset
ADBE Vector Stroke Gap #
ADBE Vector Stroke Dash #
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Graphic - G-Fill Gradient Fill
ADBE Vector Blend Mode bm12
ADBE Vector Grad Type t1
ADBE Vector Grad Start Pt s
ADBE Vector Grad End Pt e[100, 0]
ADBE Vector Grad HiLite Length h
ADBE Vector Grad HiLite Angle a
ADBE Vector Grad Colors g6
ADBE Vector Fill Opacity o100
ADBE Vector Fill Rule r1 1
ADBE Vector Composite Order if 2, it should be drawn over the previous shape 1
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Graphic - G-Stroke Gradient Stroke
ADBE Vector Blend Mode bm12
ADBE Vector Grad Typet1
ADBE Vector Grad Start Pt s
ADBE Vector Grad End Pt e
ADBE Vector Grad HiLite Length h
ADBE Vector Grad HiLite Angle a
ADBE Vector Grad Colors g6
ADBE Vector Stroke Opacity o100
ADBE Vector Stroke Width w2
ADBE Vector Stroke Line Cap lc1 1
ADBE Vector Stroke Line Join lj1 1
ADBE Vector Stroke Miter Limit ml2
ADBE Vector Stroke Dashes d
ADBE Vector Stroke Taper
ADBE Vector Stroke Wave
ADBE Vector Composite Order if 2, it should be drawn over the previous shape 1
+

Shape Modifiers

+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Merge Merge
ADBE Vector Merge Type mm
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Offset Offset Path
ADBE Vector Offset Amount a
ADBE Vector Offset Line Join lj1
ADBE Vector Offset Miter Limit ml
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - PB Pucker Bloat
ADBE Vector PuckerBloat Amount a
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Repeater Repeater
ADBE Vector Repeater Transform tr
ADBE Vector Repeater Copies c3
ADBE Vector Repeater Offset o
ADBE Vector Repeater Order m1
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - RC Rounded Corners
ADBE Vector RoundCorner Radius r10
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Trim Trim
ADBE Vector Trim Start s
ADBE Vector Trim End e
ADBE Vector Trim Offset o
ADBE Vector Trim Type m1
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Twist Twist
ADBE Vector Twist Angle a
ADBE Vector Twist Center c
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Roughen
ADBE Vector Roughen Size
ADBE Vector Roughen Detail
ADBE Vector Roughen Points
ADBE Vector Temporal Freq
ADBE Vector Correlation
ADBE Vector Temporal Phase
ADBE Vector Spatial Phase
ADBE Vector Random Seed
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Wiggler
ADBE Vector Xform Temporal Freq
ADBE Vector Correlation
ADBE Vector Temporal Phase
ADBE Vector Spatial Phase
ADBE Vector Random Seed
ADBE Vector Wiggler Transform
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Filter - Zigzag Zig Zag
ADBE Vector Zigzag Size s10
ADBE Vector Zigzag Detail r5
ADBE Vector Zigzag Points pt1
+

Transforms

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Transform Group Transform
ADBE Anchor Pointa8 [0, 0]
ADBE PositionpHalf of the comp size
ADBE Position_0Split position X
ADBE Position_1Split position Y
ADBE Position_2Split position Z
ADBE Scales7 [1, 1]
ADBE Orientationor
ADBE Rotate Xrx
ADBE Rotate Yry
ADBE Rotate Zrzor just normal rotation 0
ADBE Opacityo7 1
ADBE Envir Appear in ReflectSingle float, probably a boolean?
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Transform Group Transform Shape
ADBE Vector Anchor Pointa
ADBE Vector Anchoraprobably an outdated name
ADBE Vector Positionp
ADBE Vector Scales[100, 100]
ADBE Vector Rotate Xrx
ADBE Vector Rotate Yry
ADBE Vector Rotate Zrzor just normal rotation
ADBE Vector Rotationr
ADBE Vector Skewsk
ADBE Vector Skew Axissa
ADBE Vector Group Opacityo100
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Vector Repeater TransformRepeater Transform
ADBE Vector Repeater Anchor Pointa
ADBE Vector Repeater Positionp
ADBE Vector Repeater Scales7
ADBE Vector Repeater Rotationr
ADBE Vector Repeater Start Opacityso7 1
ADBE Vector Repeater End Opacityso7 1
+

Effects

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Tint Tint Effectty=20
ADBE Fill Fill Effectty=21
ADBE Stroke Stroke Effectty=22
ADBE Tritone Tritone Effectty=23
ADBE Pro Levels2 Pro Levels Effectty=24
ADBE Drop Shadow Drop Shadow Effectty=25
ADBE Radial Wipe Radial Wipety=26
ADBE Displacement Map Displacement Map Effectty=27
ADBE Set Matte3 Set Matte Effectty=28
ADBE Gaussian Blur 2 Gaussian Blur Effectty=29
ADBE Twirl Twirl Effectty=30
ADBE MESH WARP Mesh Warp Effectty=31
ADBE Ripple Wavy Effectty=32
ADBE Spherize Spherize Effectty=33
ADBE FreePin3 Puppet Effectty=34
+ + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Effect Built In Params Marks a LIST tdgp with built-in effect properties
ADBE Effect Mask Opacity
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Paint Group Data for the paint effect
ADBE Paint Atom Contains the following properties
ADBE Paint Duration
ADBE Paint Shape
ADBE Paint Transform Same as other transform but match names starting with ADBE Paint
ADBE Paint Properties contains the following
ADBE Paint Clone Layer
+

Text

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Text Properties Text Data
ADBE Text Document d
ADBE Text Path Options p
ADBE Text More Options m
ADBE Text Animators a
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Text Animator Text Range
ADBE Text Selectors s(list)
ADBE Text Animator Properties a
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Text Selector Text Range Selector
ADBE Text Percent Start s0
ADBE Text Percent End e100
ADBE Text Percent Offset o0
ADBE Text Index Start s
ADBE Text Index End e
ADBE Text Index Offset o
ADBE Text Range Advanced
ADBE Text Selector Max Amount a
ADBE Text Selector Smoothness sm
ADBE Text Levels Max Ease xe
ADBE Text Levels Min Ease ne
ADBE Text Random Seed rn
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Text Animator Properties Text Style
ADBE Text Anchor Point 3D a
ADBE Text Position 3D p
ADBE Text Scale 3D s
ADBE Text Skew sk
ADBE Text Skew Axis sa
ADBE Text Rotation X rx
ADBE Text Rotation Y ry
ADBE Text Rotation r
ADBE Text Opacity o
ADBE Text Fill Color fc
ADBE Text Fill Opacity fo
ADBE Text Fill Hue fh
ADBE Text Fill Saturation fs
ADBE Text Fill Brightness fb
ADBE Text Stroke Color sc
ADBE Text Stroke Opacity so
ADBE Text Stroke Hue sh
ADBE Text Stroke Saturation ss
ADBE Text Stroke Brightness sb
ADBE Text Stroke Width sw
ADBE Text Line Spacing ls
ADBE Text Line Anchor
ADBE Text Track Type
ADBE Text Tracking Amount
ADBE Text Character Replace
ADBE Text Character Offset
ADBE Text Blur
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Text Path Options Text Follow Path
ADBE Text Path m
ADBE Text Reverse Path r
ADBE Text Perpendicular To Path p
ADBE Text Force Align Path a
ADBE Text First Margin f
ADBE Text Last Margin l
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Text More Options Text Alignment Options
ADBE Text Anchor Point Option g1
ADBE Text Anchor Point Align a[0, 0]
ADBE Text Render Order 1
ADBE Text Character Blend Mode 1
+

Misc

+ + + + + + + + + + + + + + + +
Match NameDescriptionDefault
ADBE Group End Indicates the end of a LIST tdgp
+ + +

Notes

+
+
+
    +
  1. +

    Enumerations needs to be converted from floats, but the values match. 

    +
  2. +
  3. +

    Blend mode has different values than Lottie, see the section below for details. 

    +
  4. +
  5. +

    Needs to be converted from float to int

    +
  6. +
  7. +

    How to parse this? 

    +
  8. +
  9. +

    Colors are defined as 4 floats (ARGB) in [0, 255]. 

    +
  10. +
  11. +

    Colors defined as XML

    +
  12. +
  13. +

    You need to multiply by 100 to get the lottie value. 

    +
  14. +
  15. +

    For asset layers, the anchor point is relative to the size of the asset (eg: (0.5, 0.5) would be the center). 

    +
  16. +
+
+

Enumerations

+

Most enumerated values are the same in Lottie and AEP, this section lists the exceptions to this and enums not in lottie

+

Blend Mode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameAEPLottie
Normal10
Darken34
Multiply41
Color Burn57
Linear Burn6
Darker Color7
Lighten95
Screen102
Color Dodge116
Linear Dodge12
Lighter Color13
Overlay153
Soft Light169
Hard Light178
Linear Light18
Vivid Light19
Pin Light20
Hard Mix2116
Difference2310
Exclusion2411
Hue2612
Saturation2713
Color2814
Luminosity2915
+ + +

Label Colors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameDefault Color
0None(shows as grey)
1Red#b4393b
2Yellow#e2d759
3Aqua#abcbc8
4Pink#e5bcca
5Lavender#a9aac9
6Peach#e5c19f
7Sea Foam#b4c7b4
8Blue#687fdd
9Green#4ea350
10Purple#8d3299
11Orange#e79228
12Brown#7e442c
13Fuchsia#f371d5
14Cyan#43a2a4
15Sandstone#a7967a
16Dark Green#203f1f
+

Text Render Oder

+
    +
  1. Per character palette
  2. +
  3. Fills over strokes
  4. +
  5. Strokes over fills
  6. +
+

Chunk Data

+

Note that chunks might have extra data after what is described here, +always parse exactly as many bytes as specified in the chunk header.

+

LIST

+

This chunk is defined by the RIFF specs, its data has the following format:

+

Starts with an id, specifying the type of the list, then followed by sub-chunks.

+

The format of specific LIST types are described later in this document.

+

Note that the LIST btdk doesn't conform to RIFF, +so take care to not read over the chunk length.

+

Utf8

+

Contains utf-8 encoded text. Sometimes it contains the string -_0_/- which (I guess) +is used as a placeholder for objects lacking a name.

+

tdsn / fnam / pdnm

+

Contains a Utf8 chunk, used for object names

+

tdmn

+

Contains a NUL-terminated string (You'll need to strip excess \0) and defines a Match Name.

+

cmta

+

Comment, NUL-terminated string. The size seems to be variable but rounded to 4 bytes.

+

fdta

+

Folder data.

+

cdta

+

Composition data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
X Resolution2uint16
Y Resolution2uint16
1
Time Scale2uint16How much Time values are scaled by
14
Playhead2TimePlayhead time
6
In Time2TimeSame as ip in Lottie
6
Out Time2TimeSame as op in Lottie
6
Comp duration2TimeDuration setting in AE
5
Color3bytesColor as 24 bit RGB
84
Attributes1Flags
Width2uint16Same as w in Lottie
Height2uint16Same as h in Lottie
Pixel Ratio Width4uint32
Pixel Ratio Height4uint32
12
Framerate2uint16Same as fr in Lottie
16
Shutter Angle2uint16
Shutter Phase4sint16
16
Samples Limit4sint16
Samples per frame4sint16
+

Note that End Time might have a value of FFFF, if that's the case assume it to be the same as Comp Duration.

+

The X/Y resolution represent a divisor of the size in that direction used for rendering. +For example a X Resolution of 5, with a width of 500 will yield an output of 100px.

+

The pixel ratio is represented as a fraction of width/height, if both values are 1 you get square pixels.

+

Attributes:

+
    +
  • Shy: (0, 0): Hides Shy layers from the timeline
  • +
  • Motion Blur: (0, 3): Allows layers to enable motion blur
  • +
  • Frame Blending: (0, 4): Allows layers to enable frame blending
  • +
  • Preserve Framerate: (0, 5): Something about nested render queues
  • +
  • Preserve Resolution: (0, 7): Something about nested render queues
  • +
+

ldta

+

Layer data, it seems that AE23 adds 4 extra 00 bytes at the end compared to older versions.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Layer ID4uint32
Quality2uint160: Wireframe, 1: Draft, 2: Best
4
Stretch Numerator2uint16
1
Start Time2sint16Time offset for times withing the layer
6
In Time2TimeSame as ip in Lottie
6
Out Time2TimeSame as op in Lottie
6
Attributes3Flags
Source ID4uint32Item id for the used asset
17
Label Color Index1uint8Label Colors
2
Layer Name32string0It's repeated in the Utf8 chunk right after
11
Matte Mode1uint8
2
Stretch Denominator2uint16
19
Layer Type1uint8
Parent ID4uint32ID of the parent layer, if any
24
Matte Layer ID4uint32Id of the layer masking the current layer, if any (only for AE >= 23)
+

With the following Attributes:

+
    +
  • Guide: (0, 1) Guide layers aren't rendered
  • +
  • Bicubic Sampling: (0, 6)
  • +
  • Auto Orient: (1, 0)
  • +
  • Adjustment: (1, 1) Whether it's an adjustment layer
  • +
  • Threedimensional: (1, 2)
  • +
  • Solo: (1, 3) (UI thing, only displays that layer)
  • +
  • Null: (1, 7) Whether it's a null layer
  • +
  • Visible: (2, 0)
  • +
  • Effects: (2, 2)
  • +
  • Motion Blur: (2, 3)
  • +
  • Locked: (2, 5)
  • +
  • Shy: (2, 6) (Used to hide some layers in the AE UI)
  • +
  • Conitnuosly Rasterize (vector) / Collapse Transform (comps): (2, 7)
  • +
+

Layer Types:

+
    +
  • 0: Asset Layer
  • +
  • 1: Light Layer
  • +
  • 2: Camera Layer
  • +
  • 3: Text Layer
  • +
  • 4: Shape Layer
  • +
+

Matte Modes:

+
    +
  1. No Matte
  2. +
  3. Alpha
  4. +
  5. Inverted Alpha
  6. +
  7. Luma
  8. +
  9. Inverted Luma
  10. +
+

Time streching is defined as a fraction of Stretch Numerator / Stretch Denominator

+

idta

+

Item data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Type2uint16
14
ID4uint32ID used to reference this item
38
Label Color1uint8Label Colors
+

The Type field above can have the following values:

+
    +
  • 1: Folder
  • +
  • 4: Composition
  • +
  • 7: Footage
  • +
+

The last 2 bytes of this field seem to change every time you make a change.

+

tdb4

+

Property metadata.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
2Always db 99?
Components2uint16Number of values in a multi-dimensional
Attributes2Flags
1
1Some sort of flag, it has value 03 for position properties
2
2
2Always 0000 ?
22nd most significant bit always on, perhaps some kind of flag
8float64Most of the time 0.0001
8float64Most of the time 1.0, sometimes 1.777
8float64Always 1.0?
8float64Always 1.0?
8float64Always 1.0?
Type?4FlagsSee below
1Seems correlated with the previous byte, it's set for 04 for enum properties
7Bunch of 00
Animated1Set to 1 when animated, kinda the reverse of the Static bit in Attributes
7Bunch of 00
4Usually 0, probs flags
4Mst likely flags, only last byte seems to contain data
8float64Always 0.0?
8float64Mostly 0.0, sometimes 0.333
8float64Always 0.0?
8float64Mostly 0.0, sometimes 0.333
4Probs some flags
4Probs some flags
+

Attributes:

+
    +
  • Position: (1, 3). When true, this is a position property, which changes how animated values are parsed.
  • +
  • Static: (1, 0). When false, the property is animated and it will have a cdat.
  • +
+

Types:

+
    +
  • No Value: (1, 0). Used for properties like shapes, gradients, etc, where the values are not in the keyframe.
  • +
  • Integer: (3, 2).
  • +
  • Vector?: (3, 3).
  • +
  • Color: (3, 0). Set for color properties (they have a different keyframe format).
  • +
+

For Integer type, you might have indexed values: +For layers, the value will be in tdpi / tdps, +for masks it will be in tdli.

+

cdat

+

Property static value.

+

For multi-dimensional properties, you look at the number of components in tdb4 +and parse that many float64, that's the value of the property.

+

shph

+

Header for bezier shape data, contained within LIST shap.

+

It's followed by a LIST list with bezier data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
3
Attributes1Flags
Top Left2float32Top-left corner of the shape area, relative to the layer position
Bottom Right2float32Bottom-right corner of the shape area, relative to the layer position
4
+

Flags:

+
    +
  • Open: (0, 3). When true, the shape is open (it's missing the segment connecting the last point to the first)
  • +
+

lhd3

+

Inside a LIST list, defines the data format, followed by ldat.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
4Seems to always be 00 d0 0b ee
6All 00
Count2uint16Number of items
4The last byte is the only one that changes, greatest variation is on shapes
2All 00
Item Size2uint16Size of an item in the list
3All 00
Type?1
400 00 00 01
2All 00
2Some kind of flags
20All 00
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Item TypeSizeType
Gide00 0102
LItm00 8001
LRdr08 c601
Color Kf00 9804
1D Kf00 3004
2D Kf00 5804
2D pos Kf00 6804
3D Kf00 8004
3D pos Kf00 8004
Marker Kf00 1004
Orientation Kf00 5004
No Value Kf00 4004
+

The corresponding ldat should have Item Size * Count bytes, and it's omitted if Count is 0.

+

ldat

+

Inside a LIST list, contains the list data, preceded by lhd3.

+

The number of element is the one defined in lhd3.

+

It has a different format based on certain conditions, follow some of the possible element formats.

+

The size of an item is found like so:

+
item_size = ldat_chunk_length / lhd3_count
+
+

Keyframe (common)

+

All keyframe items start like this:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
1
Time2TimeTime of the keyframe, seems they always start from 0.
2
Ease Mode1uint8
Label Color1uint8Label Colors
Attributes1Flags
+

Ease Mode: +1. Linear +2. Ease +3. Hold

+

Attributes:

+

Least significant 3 bits seems to always be on.

+
    +
  • Continuous Bezier (0, 3)
  • +
  • Auto Bezier (0, 4)
  • +
  • Roving across time (0, 5)
  • +
+

Keyframe - Multi-Dimensional

+

Given n as the number of dimensions found in tdb4 (eg: 3 for 3D positions):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Value8* nfloat64[n]Value
In Speed8* nfloat64[n]
In Influence8* nfloat64[n]
Out Speed8* nfloat64[n]
Out Influence8* nfloat64[n]
+

Keyframe - Position

+

If the property is an animated position, the keyframe is formatted like so:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
8
8float64
In Speed8float64
In Influence8float64
Out Speed8float64
Out Influence8float64
Value8* nfloat64[n]Value
Tan In8* nfloat64[n]Spatial tangents
Tan Out8* nfloat64[n]Spatial tangents
+

Keyframe - No Value

+

Used for shapes and gradients (Special set in tdb4)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
8
8float64
In Speed8float64
In Influence8float64
Out Speed8float64
Out Influence8float64
8
+

Keyframe - Color

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
8
8float64
In Speed8float64
In Influence8float64
Out Speed8float64
Out Influence8float64
Value8*4float64[4]ARGB 255
8*8float64[8]
+

Shape Data

+

Bezier data, positions are relative to the area defined by shph.

+

The list is a sequence of points, appearing in this order:

+
    +
  • Vertex 0
  • +
  • Out Tangent 0
  • +
  • In Tangent 1
  • +
  • Vertex 1
  • +
  • Out Tangent 1
  • +
  • ...
  • +
+

Note that all coordinates are relative to the area in shph but not to each other.

+

A coordinate of [0, 0] will correspond to the top-left corner in shph, +and [1, 1] corresponds to the bottom-right.

+ + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
X4float32X Coordinate
XY4float32X Coordinate
+

pprf

+

Color profile information as ICC data.

+

fiac

+

Folder item active, uint8 if it's 1 the previous List Item is the active item.

+

wsnm

+

Worspace name.

+

Utf-16 encoded string, contains the name of the "workspace" (window layout in AE)

+

It's always followed by an Utf8 with the same content.

+

tdum / tduM

+

float64 values often found inside LIST tdbs.

+

In some cases they seem to indicate minimum and maximum values for that +property but there are some cases in which they are both 0.0.

+

ppSn

+

Contains a float64, unknown meaning.

+

otda

+

Orientation data

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
X8float64X Coordinate
Y8float64Y Coordinate
Z8float64Z Coordinate
+

opti

+

Asset data, format depends on type

+ + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Type4stringAsset type
+

Solid

+

Type Soli, data for solid layers.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
6
Alpha4float32
Red4float32
Green4float32
Blue4float32
Name256string0
+

Color components are in [0, 1].

+

sspc

+

Footage / asset data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
32
Width2uint16
2
Height2uint16
+

alas

+

JSON string containing external asset info.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameTypeDescription
ascendcount_basenumber
ascendcount_targetnumber
fullpathstringThe absolute path to the file
platformnumberOperating system (see below)
server_namestringHostname (?)
server_volume_namestring
target_is_folderbooleanWhether the file is a folder
+

platform values: 1 is Windows, other values are for Unix and MacOS, +but the values are to be discovered

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
AE Version?6
12
File Revision?2uint16Increases by 2 every time you save
+

Seems the first 6 bytes contain AE version information.

+

I haven't been able to decode it fully but here's a list of values +encountered in the wild:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VersionBytes
15.05c 06 07 38 06 b4
16.05d 04 0b 00 06 eb
16.0.15d 04 0b 00 0e 30
16.1.25d 05 0b 00 96 37
16.1.35d 05 0b 00 9e 05
17.05d 09 4b 08 06 2b
17.0.45d 0b 0b 08 26 3b
18.2.15d 1b 0b 11 0e 08
18.45d 1d 0b 12 06 26
22.05d 1d 0b 70 06 6f
22.65d 2b 0b 33 06 3b
23.2.15e 03 0b 39 0e 03
+

It's possible the 3rd to the 5th bytes encode some kind of internal build +number that gets mapped to AE versions somehow...

+

EfDC

+

The first byte contains the number of LIST EfDf in a LIST EfdG

+

parn

+

Contains a uint64 with the number of parameters in a LIST parT.

+

pard

+

Effect parameter definition.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
15
Type1uint8Parameter type
Name32string0
8
+

Types:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Type NameAEPLottieLottie Object
Layer010Effect Value Layer
Scalar20Effect Value Slider
Angle31Effect Value Angle
Boolean44Effect Value Checkbox
Color52Effect Value Color
2D63Effect Value Point
Enum77Effect Value Drop Down
Paint Group9
Slider100Effect Value Slider
Group135Custom Effect
Unknown156Effect No Value
3D183Effect Value Point
+

After the data above, there is more data that depends on the type

+

Layer

+

Doesn't seem to have much data

+

Scalar / Angle

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last value4sint32
4
64
4
Min Value2sint16
2
Max Value2sint16
+

To get the last value, you need to divide the raw value by 0x10000.

+

Boolean

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last used value4uint32
Default1uint8
3
64
4float32
4
4float32
+

Color

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last used value4uint8[4]ARGB
Default4uint8[4]ARGB
64
Max Value4uint8[4]ARGB
+

2D

+ + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last value X4sint32
Last value Y4sint32
+

Last value x/y are multiplied by 0x80, so divide them to get the right value.

+

Enum

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last used value4uint32
Option count2uint16
Default2uint16
+

Slider

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last used value8float64
44
4float32
4
Max Value4float32
+

3D Point

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameSizeTypeDescription
Last value X8float64
Last value Y8float64
Last value Z8float64
+

You need to multiply the "Last value" components by 512 to get the actual values.

+

pdnm

+

Effect parameter definition name / strings.

+

This will contain strings used by the widget in the effect controls of the preceding pard.

+

For example if the type in the pard is 4 (Boolean) the name of the parameter might be +empty and it will be in pdnm as that's how AE displays it.

+

For Enum (type 7), you get the drop down strings separated by |.

+

tdpi

+

Layer index for index properties (uint32).

+

tdps

+

Layer source for index properties (sint32).

+
    +
  • 0: Layer
  • +
  • -1: Effects & Masks
  • +
  • -2: Masks
  • +
+

tdli

+

Mask index for index properties (uint32).

+

prin

+

Seems to always have the same content:

+

4 00 bytes, the string ADBE Escher, 37 00, the string Classic 3D, +41 00, and ends with 01.

+

prda

+

Seems to always have the same content: 3 00, a 01, 8 00.

+

NmHd

+

Marker attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameSizeTypeDescription
3
Attributes1Flags
Duration4uint32Duration in frames
4
Label Color1uint8Label Colors
+

Flags:

+
    +
  • Protected: (0, 1) The marker signals a protected region
  • +
  • ???: (0, 2) This flags seems to always be on
  • +
+

tdsb

+

4 bytes specifying flags for a tdgp.

+
    +
  • 0x00'00'00'01 - object is visible
  • +
  • 0x00'00'00'02 - split position
  • +
  • 0x00'00'20'00 - locked x/y ratio
  • +
+

mkif

+

Mask properties.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameSizeType
Inverted1uint8
Locked1uint8
4
Mode2uint16
+

Mask Modes:

+
    +
  • 0: None
  • +
  • 1: Add
  • +
  • 2: Subtract
  • +
  • 3: Intersect
  • +
  • 4: Darken
  • +
  • 5: Lighten
  • +
  • 6: Difference
  • +
+

CCId

+

Composition ID for essential graphics properties (uint32)

+

CLId

+

Layer ID for essential graphics properties (uint32)

+

Smin

+

Essential graphics slider minimum value.

+

Representation depends on the value of the previous CTyp.

+

Smax

+

Essential graphics slider maximum value.

+

Representation depends on the value of the previous CTyp.

+

CVal

+

Essential graphics property current value.

+

Representation depends on the value of the previous CTyp.

+

CDef

+

Essential graphics property default value.

+

Representation depends on the value of the previous CTyp.

+

CTyp

+

uint32 with the essential graphics item type

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeValue Format
Scalar2float64
Color4float32[4] RGBA
Position5float64[2]
Comment8
Vector9float64[4]
Group10
Enum13uint32
+

CprC

+

Essential graphics flags (4bytes)

+
    +
  • Is property (3, 0)
  • +
+

StVS

+

Essential graphics group item count

+ + + + + + + + + + + + + + + + + + + + +
NameSizeType
Count1uint8
3
+

CDim

+

uint32 number of dimensions for an essential vector property.

+

fips

+

Contained in LIST Fold contains preview settings. +The chunk is repeated multiple times but only the first one seems +to be relevant.

+ + + + + + + + + + + + + + + + + + + + +
NameSizeType
15
Flags1uint8
+

Flags

+
    +
  • Show alpha grid (0, 7)
  • +
+

LIST Fold

+

Top level item.

+

LIST Item

+

Item, you can check its properties with idta contained inside it.

+

LIST Layr

+

Defines a layer.

+

Layer metadata is found in a ldta, the layer name is in a Utf8.

+

Go through its LIST tdgp to get shapes and transforms.

+

You will find the following match names within it:

+
    +
  • ADBE Root Vectors Group: Contains shape data (shape layer in lottie)
  • +
  • ADBE Camera Options Group: Lottie camera layer
  • +
  • ADBE Transform Group: Layer transform
  • +
  • ADBE Layer Styles: Layer styles
  • +
+

LIST tdgp

+

Defines an object / property group.

+

Flags for the objects are in tdsb.

+

The name of the object is in tdsn > Utf8.

+

Then follows a sequence of properties / objects defined as such:

+

tdmn specifies the match name of the object, then it's followed by +chunks that describe said object (usually more LISTs).

+

Usually the last chunk here is a tdmn with value ADBE Group End.

+

LIST tdbs

+

Defines an object's property. To know which property, you need to +check the tdmn preceding this chunk.

+

It will contain a tdb4, and usually cdat (static) or a List list (animated).

+

For properties with expressions, it will have a Utf8 with the expression code.

+

LIST GCst

+

Defines a gradient.

+

Contains a LIST tdbs and a LIST GCky.

+

LIST GCky

+

Gradient color keyframes.

+

Contains a sequence of Utf8 formatted in XML with the gradient definition +for each keyframe.

+

LIST om-s

+

Contains a LIST tdbs and a LIST omks to define a shape property.

+

LIST omks

+

Bezier shape data.

+

Contains a sequence of LIST shap with the shape data for each keyframe.

+

LIST shap

+

Contains a shph and a LIST list with the shape data.

+

LIST CPPl

+

Contains a pprf.

+

LIST list

+

For animated properties it replaces cdat.

+

The list header is defined in the chunk lhd3, the list data in ldat.

+

LIST SLay / LIST DLay / LIST CLay

+

They seem to be camera layers used to store internal views, not exported to lottie.

+

SLay (Side views?) have names like "Top" and "Front", perhaps they define 3d views.

+

CLay: Custom views.

+

DLay: Default views.

+

LIST SecL

+

Composition Markers Layer.

+

Contains ldta and like other layers.

+

in LIST tbgp look for the match name ADBE Marker, the data is in +the LIST mrst.

+

LIST mrst

+

Marker property.

+

Contains a LIST tdbs that defines the property, which should always be animated +when present.

+

Marker keyframe values are available in LIST mrky.

+

LIST mrky

+

Marker keyframes.

+

contains a LIST Nmrd for each keyframe

+

LIST Nmrd

+

Marker data

+

There's a NmHd with the attributes.

+

The marker comment is in the first Utf8

+

LIST otst

+

Orientation property.

+

Contains a LIST tdbs and a LIST otky to define a shape property.

+

LIST otky

+

Contains a sequence of otda with the orientation data for each keyframe.

+

LIST Als2

+

Contains alas for external assets.

+

LIST Sfdr

+

Asset folder contents, contains several LIST Item.

+

LIST btdk

+

For some reason this doesn't conform to the RIFX specs, instead of a list +its data is encoded in Carousel Object Structure (COS).

+

The COS format is the same used in PDF but it's extremely difficult to +find detailed information on it, the best technical specs is this very old +PDF 1.7 specification.

+

Once you parse the COS, you can find the following data:

+
    +
  • 0.1.0: Array of available fonts:
      +
    • 0.99: CoolTypeFont
    • +
    • 0.0.0: Font family (seems to have bold/italic encoded in the name)
    • +
    • 0.0.2: 0 or 1?
    • +
    +
  • +
  • 1.1: Array of text documents (one for each keyframe) in this format:
      +
    • 0.0: Text
    • +
    • 0.5.0: Array of paragraph styles
        +
      • 0.0.5 Paragraph Style:
          +
        • 0: Text align (0: left, 1: right, 2: center)
        • +
        +
      • +
      • 1: Length (in characters) the style applies to
      • +
      +
    • +
    • 0.6.0: Array of character styles:
        +
      • 0.0.6: Character Style:
          +
        • 0: Index of the font from the array of available fonts
        • +
        • 1: Font size
        • +
        • 2: Faux Bold
        • +
        • 3: Faux Italic
        • +
        • 12: 0: Normal, 1: Small caps, 2: All caps
        • +
        • 13: 0: Normal, 1: Superscript, 2: Subscript
        • +
        • 53.0.1: Fill color in ARGB [0, 1]
        • +
        • 54.0.1: Stroke color in ARGB [0, 1]
        • +
        • 57: Stroke enabled
        • +
        • 58: Stroke over fill
        • +
        • 63: Stroke width
        • +
        +
      • +
      • 1: Length (in characters) the style applies to
      • +
      +
    • +
    +
  • +
+

LIST sspc

+

Effect Definiton.

+

The generic effect name is in fnam > Utf8.

+

The effect parameters are defined in LIST parT. +If the effect type has already been encountered, you might not find the +LIST parT here, you might need to match the name to an entry in LIST EfdG.

+

It finally contains a LIST tdgp where the effect properties are present +like any other animated property. You can also find the name +of the effect object in fnam > Utf8.

+

Inside there you can also find a match name with ADBE Effect Built In Params +which will contain values for built-in effect parameters.

+

LIST parT

+

Effect parameters.

+

Contains a parn with the number of parameters, then follows +a list of tdmn with the match name of the parameter followed by +pard with its definition.

+

Enum parameters have their values in a pdnm separated by | pipes.

+

The first property seems to be a dummy?

+

LIST EfdG

+

Effect definitions.

+

This is where effect types used by the project are defined.

+

Basically it repeats the first instance of any effect found in the layers.

+

it contains a EfDC with the number of effects, and that many LIST EfDf.

+

LIST EfDf

+

Effect type definition.

+

Contains a tdmn with the match name of the effect and a LIST sspc.

+

LIST ExEn

+

Contains a Utf8 with the expression language (eg: javascript-1.0).

+

LIST PRin

+

Contains a prin and a prda.

+

LIST Pin

+

Asset properties.

+

Contains:

+
    +
  • sspc with some common properties
  • +
  • Utf8 with the name (except for solids)
  • +
  • opti with asset data
  • +
+

LIST CIF0

+

See LIST CIF3.

+

LIST CIF2

+

See LIST CIF3.

+

LIST CIF3

+

Essential Graphics Definition.

+

LIST CCtl

+

Essential graphics item.

+

LIST CpS2

+

Essential graphics header.

+

LIST StVc

+

Essential graphics group items

+

LIST CPrp

+

Essential graphics property definition

+

LIST OvG2

+

Essential graphics override property identifiers

+

LIST CPrp

+

Essential graphics override property identifier

+

LIST LRdr

+

Render queue data. this is a top-level chunk. Items are stored in LIST LItm.

+

LIST LItm

+

Render Queue items, contains a sequence of LIST list and +LIST LOm, the latter having information on the render item (one per job).

+

LIST LOm

+

Render list item, contains the following chunks:

+
    +
  • Roou Output options?
  • +
  • Ropt Render options?
  • +
  • LIST Als2 Selected output file
  • +
  • Utf8 Name of the template applied to the item
  • +
  • Utf8 File name template
  • +
+

Gradient XML

+

Gradient data seems to be stored in a convoluted XML structure.

+

The easiest way to describe it is as a mapping, the elements can be parsed like so:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tag NameLogical TypeDescription
prop.mapTop-level, just get its first child
prop.listdictMapping of key-value pairs
prop.pairItem in prop.list
keystrProperty key
arraylistArray of values, the first item is array.type which specifies the type
intint
floatfloat
stringstr
+

If you interpret the XML as a mapping, you can gather the following info:

+
{
+    "Gradient Color Data":
+    {
+        "Alpha Stops":
+        {
+            "Stops List":
+            {
+                "Stop-0":
+                {
+                    "Stops Alpha":
+                        [
+                            0.0, // offset
+                            0.5, // midpoint
+                            1.0  // alpha
+                        ]
+                },
+                // More stops defined the same way...
+            }
+            "Stops Size": 2 // Number of stops
+        },
+        "Color Stops":
+        {
+            "Stops List":
+            {
+                "Stop-0":
+                {
+                    "Stops Color":
+                    [
+                        0.0, // offset
+                        0.5, // midpoint
+                        0.0, // red
+                        0.0, // green
+                        0.5, // blue
+                        1.0  // alpha?
+                    ]
+                },
+                // More stops defined the same way...
+            }
+            "Stops Size": 2 // Number of stops
+        }
+    },
+    "Gradient Colors": "1.0" // Version?
+}
+
+

Midpoint

+

You should use the "midpoint" values to add an additional color which is halfway between the other two.

+

For example given these stops:

+
    "Stop-0":
+    {
+        "Stops Color":
+        [
+            0.0, // offset
+            0.5, // midpoint
+            0.1, // red
+            0.2, // green
+            0.3, // blue
+            1.0  // alpha?
+        ]
+    },
+    "Stop-0":
+    {
+        "Stops Color":
+        [
+            0.6, // offset
+            0.5, // midpoint
+            0.3, // red
+            0.4, // green
+            0.5, // blue
+            1.0  // alpha?
+        ]
+    },
+
+

The final gradient will look like this:

+
[
+    // stop 0
+    0.0, // offset_0
+    0.1, // red_0
+    0.2, // green_0
+    0.3, // blue_0
+    // midpoint stop
+    0.3, // offset_0 * (1 - midpoint_0) + offset_1 * midpoint_0
+    0.2, // (red_0 + red_1) / 2
+    0.3, // (green_0 + green_1) / 2
+    0.4, // (blue_0 + blue_1) / 2
+    // stop 1
+    0.6, // offset_1
+    0.5, // midpoint_1
+    0.3, // red_1
+    0.4, // green_1
+    0.5, // blue_1
+]
+
+

Opacity

+

For some reason in AE gradients alpha is independent from the color, so you have separate stops for +color and opacity.

+

You should treat the midpoint value for opacity stops in a similar way as to the color ones.

+

Once you have both the color and opacity values, the final lottie array is simply a concatenation of the two.

+

XMP Metadata

+

After the RIFX data, an AEP file also contains some XML in the +XMP format.

+

This section contains the version of AfterEffects, when the file has been +created and modified, and related info.

+

XML Project Format

+

Aftereffects allows you to save the project as XML.

+

This is basically as the RIFX but with a different container format and +binary data encoded as hex.

+

Conversion notes for elements are provided below

+

AfterEffectsProject

+

Root element, same as RIFX.

+

ProjectXMPMetadata

+

In the RIFX file this is dumped at the end without a chunk.

+

string

+

Used instead of Utf8.

+

numS / ppSn

+

For some reason they have their value in a <string> but are not string in the RIFX.

+

tdsn / fnam / pdnm

+

These elements contain children but they are not LIST in RIFX, that's the only thing of note.

+

Child elements

+

If an element has children. it's the same as the equivalent LIST in RIFX.

+

bdata

+

Elements with the bdata attribute have their binary data hex encoded in said attribute.

+

You can parse their data the same way as you'd do in RIFX.

+

Resources

+
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/animation/index.html b/animation/index.html new file mode 100644 index 00000000..af7103e0 --- /dev/null +++ b/animation/index.html @@ -0,0 +1,734 @@ + + + + + + + + + + + + + + Animation - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Animation

+

This is the top-level JSON object, describing the document, layers, assets, etc.

+

The size of the canvas is determined by w and h. Duration is expressed in frames with op, and the framerate is in fr.

+

Most of the contents are in layers and assets.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
layersarray of Precomposition Layer or Solid Color Layer or Image Layer or Null Layer or Shape Layer or Text Layer or Audio Layer or Camera Layer or Data Layer +

An array of layers (See: Lists of layers and shapes)

+
nmstring +

Name, as seen from editors and the like

+
mnstring +

Match name, used in expressions

+
assetsarray of Image or Precomposition or Sound or Data source +

An array of assets

+
vstring +

Lottie version, on very old versions some things might be slightly different from what is explained here

+
ddd0-1 integer +

Whether the animation has 3D layers. Lottie doesn't actually support 3D stuff so this should always be 0

+
frnumber +

Framerate in frames per second

+
ipnumber +

"In Point", which frame the animation starts at (usually 0)

+
opnumber +

"Out Point", which frame the animation stops/loops at, which makes this the duration in frames when ip is 0

+
winteger +

Width of the animation

+
hinteger +

Height of the animation

+
compsarray of Precomposition +

List of Extra compositions not referenced by anything

+
fontsFont List +

Fonts

+
charsarray of Character Data +

Data defining text characters as lottie shapes. If present a player might only render characters defined here and nothing else.

+
metaMetadata +

Document metadata

+
metadataUser Metadata +

User Metadata

+
markersarray of Marker +

Markers defining named sections of the composition.

+
mbMotion Blur +

Motion Blur

+
slotsobject +

Available property overrides

+
+
+

Metadata

+

Some (but not all) lottie files will have a metadata object describing the +program used to create the file and other useful information:

+

Document Metadata

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
astring +

Author

+
dstring +

Description

+
tcstring +

Theme Color

+
gstring +

Software used to generate the file

+
+
+

User Metadata

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
filenamestring +

Filename

+
customPropsobject +

Custom Properties

+
+
+

Motion Blur

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
sanumber +

Angle in degrees

+
spnumber +

Angle in degrees

+
spfnumber +

Samples per Frame

+
aslnumber +

Adaptive Sample Limit

+
+
+

Marker

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
cmstring +

Comment

+
tmnumber +

Time

+
drnumber +

Duration

+
+
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/index.html b/assets/index.html new file mode 100644 index 00000000..572b301f --- /dev/null +++ b/assets/index.html @@ -0,0 +1,728 @@ + + + + + + + + + + + + + + Assets - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Assets

+

Assets are usually referenced by layers of the appropriate type.

+

Image

+

Represents a (static) image

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
idstring +

Unique identifier used by layers when referencing this asset

+
nmstring +

Human readable name

+
ustring +

Path to the directory containing a file

+
pstring +

Filename or data url

+
e0-1 integer +

Whether the file is embedded

+
wnumber +

Width of the image

+
hnumber +

Height of the image

+
tstring = 'seq' +

Marks as part of an image sequence if present

+
sidstring +

One of the ID in the file's slots

+
+
+

If the image is embedded, u is empty and p contains a base64-encoded data url:

+
{
+    "id": "my image",
+    "h": 512,
+    "w": 512,
+    "e": 1,
+    "u": "",
+    "p": "data:image/png;base64,..."
+}
+
+

If the image is not embedded, +u will contain the path to the directory containing the image +and p will have the filename.

+

So for example if you want to store the image at /path/to/images/image.png, +the asset will look something like this:

+
{
+    "id": "my image",
+    "h": 512,
+    "w": 512,
+    "e": 0,
+    "u": "/path/to/images/",
+    "p": "image.png"
+}
+
+

It works similarly for external images. +If you want to store the image at https://example.com/images/image.png, you'd have:

+
{
+    "id": "my image",
+    "h": 512,
+    "w": 512,
+    "e": 0,
+    "u": "https://example.com/images/",
+    "p": "image.png"
+}
+
+

Sound

+

Similar to Image but for audio files.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
idstring +

Unique identifier used by layers when referencing this asset

+
nmstring +

Human readable name

+
ustring +

Path to the directory containing a file

+
pstring +

Filename or data url

+
e0-1 integer +

Whether the file is embedded

+
+
+

Precomposition

+

You can think of precompositions as self-contained animation within the +main animation file that can be referenced using precomp layers.

+

Within a precomposition you can have precomp layers showing other precompositions, +as long as you don't create a dependency cycle.

+

You can find more details in the Precompositions page.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
layersarray of Precomposition Layer or Solid Color Layer or Image Layer or Null Layer or Shape Layer or Text Layer or Audio Layer or Camera Layer or Data Layer +

An array of layers (See: Lists of layers and shapes)

+
idstring +

Unique identifier used by layers when referencing this asset

+
nmstring +

Human readable name

+
frnumber +

Framerate in frames per second

+
xt0-1 integer +

Extra composition

+
+
+

Follows a rather extreme example, that uses precompositions inside precompositions to generate a fractal:

+

+

+
+
+
+
+ +
+

+

Data Source

+

Points to a JSON file for data.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
idstring +

Unique identifier used by layers when referencing this asset

+
nmstring +

Human readable name

+
ustring +

Path to the directory containing a file

+
pstring +

Filename or data url

+
e0-1 integer +

Whether the file is embedded

+
tinteger = 3 +

Type

+
+
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/breakdown/bezier/index.html b/breakdown/bezier/index.html new file mode 100644 index 00000000..29dbec14 --- /dev/null +++ b/breakdown/bezier/index.html @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + Bezier Curves - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Bezier Curves

+

+

+
+
+
+
+ +
+

+

Introduction to Beziers

+

Bezier curves are a common way of approximating arbitrary shapes in computer graphics.

+

They represent an arc of a polynomial, and they can be of any degree, but usually you will mostly find quadratic and cubic beziers.

+

Lottie only deals in cubic beziers so we'll focus on those.

+

A bezier curve of degree n is defined by n+1 points.

+

The first and the last of such points will lay on the curve, while the others define the shape of the segment.

+

So for the case of a cubic bezier (degree 3) you have 4 points.

+

To find a point on a bezier, you usually define it as the result of an interpolation +within the polynomial curve. The interpolation factor is usually referred to as t.

+

The easiest way of calculating the poition of a point in a bezier given a t is to +perform linear interpolations between the bezier points, each step reducing the +curve to one with a degree less than the previous, until you end up with a final point.

+

For example in the cubic case, you interpolate each cubic point with the next, +resulting in 3 quadratic points.

+

You repeat the process on these 3 points, and you end up with 2 other points.

+

Finally you perform linear interpolation between the two to get the result.

+

In the example below you can control the t value to see how this algorithm works. +The black dots are the ones that define the bezier, and the red dot is the position +along the bezier at the given t.

+
+ + + + + +
0.5
+
+
+
+
+ +
+

Poly Beziers

+

Usually shapes are defined as a polybezier, which is the a concept equivalent to +polygons, but with bezier segments as their edges.

+

Each bezier segment has its last point in the same position as the first point in the following segment.

+

This results in a sequence of points, some of which are along the line and some of which +are not.

+

For polybeziers with cubic segments, there are two points outside the path between each pair of points along the path.

+

For this reason instead of viewing the polybezier as a sequence of bezier segments, +they are often seen as a sequence of vertices and tangents.

+

The vertices are the points along the path, which correspond to the end points of the segments.

+

Each point has two tangents associated with them, one "in" thangent, and one "out" tangent.

+

The "out" tangent is the second point defining the bezier segment following the vertex +and the "in" tangent is the third point defining the bezier segment coming into the vertex.

+

Beziers in Lottie

+

An shape in Lotttie is represented as a cubic polybezier and it's represented in the JSON +as an object with the following attributes:

+

v is an array of vertices.

+

i is an array of "in" tangent points, relative to v.

+

o is an array of "out" tangent points, relative to v.

+

c is a boolean determining whether the polybezier is closed. +If it is, there's an additional bezier segment between the last point in v and the first.

+
+
+ + +
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/breakdown/bouncy_ball/index.html b/breakdown/bouncy_ball/index.html new file mode 100644 index 00000000..c818d90c --- /dev/null +++ b/breakdown/bouncy_ball/index.html @@ -0,0 +1,872 @@ + + + + + + + + + + + + + + Bouncy Ball - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Bouncy Ball

+

This page will show the basics of Lottie by inspecting this simple animation:

+

+

+
+
+
+
+ +
+

+

Note that Lottie files usually have their JSON minified, but the example files +here have been expanded for ease of inspection.

+

This dissection is not meant to be a complete description, so certain attributes +will not be described but each section will have links to the relevant reference +pages where you can find a description for those.

+

Top level

+

The top level object, describes the animation as a whole.

+
{
+    "nm": "Bouncy Ball",
+    "v": "5.5.2",
+    "ip": 0,
+    "op": 120,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "layers": [
+        ...
+    ]
+}
+
+

Here we see the basic properties:

+

nm is the name of the document, it's not actually used by players.

+

v shows the Lottie format version, some older files might have a slightly different structure.

+

fr is the framerate in frames per second. +Note that most timing information is described in frames within Lottie, +so changing the framerate means the duration of the animation will also change.

+

op is the last frame of the animation, after which the animation will loop or stop, +depending on how the player is set up. +In this case 120 frames at 60 fps will result in 2 seconds of animation.

+

ip marks the first frame of the animation, usually it's set to 0.

+

w and h describe the width and height of the animation, +any content outside the box starting at (0, 0) and ending at (w, h) will not be visible.

+

Note that a lottie file is a vector format and can be scaled up and down. +So you shouldn't think of these values as a size in pixels.

+

Layers

+

Now we look at the layers.

+

Most file will be more complex than this and have multiple layers but here we only have one:

+
 {
+    "ddd": 0,
+    "ty": 4,
+    "ind": 0,
+    "st": 0,
+    "ip": 0,
+    "op": 120,
+    "nm": "Layer",
+    "ks": {
+        ...
+    },
+    "shapes": [...]
+}
+
+

We see the layer can also have a name (nm).

+

You might note that ip and op have the same values as in the animation. +This means the layer will always be visible. +You can decide to show a layer only for a small amount of time, in which case +you would set ip to the first frame the layer should be visible at and +op to the last frame, and the layer will only be visible between those frames.

+

ddd is a boolean value that indicates whether this layer contains 3D elements.

+

ty is the layer type. In this case it's a shape layer.

+

Finally ind is a unique number used to reference this layer. +Here it's not being used since there is only one layer.

+

Layer transform

+

Here we'll have a look at the ks attribute of the layer that represents its transform:

+
{
+    "a": {
+        "a": 0,
+        "k": [
+            0,
+            0
+        ]
+    },
+    "p": {
+        "a": 0,
+        "k": [
+            0,
+            0
+        ]
+    },
+    "s": {
+        "a": 0,
+        "k": [
+            100,
+            100
+        ]
+    },
+    "r": {
+        "a": 0,
+        "k": 0
+    },
+    "o": {
+        "a": 0,
+        "k": 100
+    }
+}
+
+

This layer does not have any transform so everything is at its default value. +(If you see a transform missing some attributes, you can assume they have the values above)

+

You might have noticed that all the attributes of the transform are objects with the same structure.

+

This is because they are animatable properties. +In this case they don't have any animations applied to them so a is 0 and k is the actual value.

+

If they were animated, a would be 1 and k would have a list of keyframes (more on this later).

+

The animated properties of a transform are as follows:

+

a is the anchor point along which other transformations are applied (you can think of it as the center of rotation).

+

p is the position (translation). Both a and p have arrays as values representing 2D coordinates.

+

s is the scale and, similar to a and p, its value has 2 components. +Note that values are expressed as percentages (100 meaning 100% or no scaling).

+

r is the rotation angle in degrees.

+

o is opacity, similar to s, it also is expressed as a percentage.

+

You might also find sk and sa in a transform object, determining the skew.

+

Shapes

+

Since this is a shape layer, it contains a list of shapes.

+

In this case there is only one shape:

+
{
+    "ty": "gr",
+    "nm": "Ellipse Group",
+    "it": [ ... ]
+}
+
+

ty represents the type of the shape, in this case it's a group, +which is simply a shape that contains other shapes.

+

Groups add another layer of organization: you have layers at the top, +shape layers can contain group shapes, and groups can contain other groups.

+

nm is the name, same as before.

+

it is the list of shapes within the group, we will inspect them one by one

+

Ellipse

+
{
+    "ty": "el",
+    "nm": "Ellipse",
+    "p": {
+        "a": 0,
+        "k": [
+            204,
+            169
+        ]
+    },
+    "s": {
+        "a": 0,
+        "k": [
+            153,
+            153
+        ]
+    }
+}
+
+

The first shape in the group is an ellipse (denoted by "ty": "el").

+

It has two properties: position (p) and size (s).

+

The position determines the center of the ellipse and size its two axes. +In this case we can tell it's a circle since both values in s are the same.

+

Fill

+
{
+    "ty": "fl",
+    "nm": "Fill",
+    "o": {
+        "a": 0,
+        "k": 100
+    },
+    "c": {
+        "a": 0,
+        "k": [
+            0.710,
+            0.192,
+            0.278
+        ]
+    },
+    "r": 1
+}
+
+

An ellipse by itself doesn't actually draw anything. it just defines the shape.

+

So we need to apply some style to it. Here we have a fill shape +that determines the fill color for the ellipse.

+

r is not animated and it determines the fill rule.

+

o is the opacity, as a percentage.

+

c is a color. Colors are RGB triplets with components in [0, 1].
+In this case it represents this color: [0.71, 0.192, 0.278].

+

Transform

+
{
+    "ty": "tr",
+    "a": {
+        "a": 0,
+        "k": [
+            204,
+            169
+        ]
+    },
+    "p": { ... },
+    "s": { ... },
+    "r": {
+        "a": 0,
+        "k": 0
+    },
+    "o": {
+        "a": 0,
+        "k": 100
+    }
+}
+
+

Unlike layers, that have the transform as an attribute, groups have them as a shape.

+

Note that this might give you a false sense of flexibility, because players +expect to have a transform shape at the end of their shape list.

+

The attributes are the same as the layer transform, with the addition of ty +to represent the shape type.

+

Here position (p) and scale (s) are animated and we'll look into them separately:

+

Animated Position

+
{
+    "a": 1,
+    "k": [
+        {
+            "t": 0,
+            "s": [
+                235,
+                106
+            ],
+            "h": 0,
+            "o": {
+                "x": [
+                    0.333
+                ],
+                "y": [
+                    0
+                ]
+            },
+            "i": {
+                "x": [
+                    1
+                ],
+                "y": [
+                    1
+                ]
+            }
+        },
+        {
+            "t": 60,
+            "s": [
+                235,
+                441
+            ],
+            "h": 0,
+            "o": {
+                "x": [
+                    0
+                ],
+                "y": [
+                    0
+                ]
+            },
+            "i": {
+                "x": [
+                    0.667
+                ],
+                "y": [
+                    1
+                ]
+            }
+        },
+        {
+            "t": 120,
+            "s": [
+                235,
+                106
+            ]
+        }
+    ]
+}
+
+

a is 1, denoting the property is animated. k contains a list of keyframes.

+

First Keyframe

+
{
+    "t": 0,
+    "s": [
+        235,
+        106
+    ],
+    "h": 0,
+    "o": {
+        "x": [
+            0.333
+        ],
+        "y": [
+            0
+        ]
+    },
+    "i": {
+        "x": [
+            1
+        ],
+        "y": [
+            1
+        ]
+    }
+}
+
+

The first keyframe specifies the time at which the property starts being animated.

+

In this case t is 0, meaning the animation starts right away.

+

s shows the value the property will have at t.

+

o and i specify the easing function.

+

o affects the movement at the beginning of the keyframe and i at the end.

+

In this case, it uses an "ease in" kind of curve, where the animation starts +slowly and it picks up speed at the end.

+

Second Keyframe

+
{
+    "t": 60,
+    "s": [
+        235,
+        441
+    ],
+    "h": 0,
+    "o": {
+        "x": [
+            0
+        ],
+        "y": [
+            0
+        ]
+    },
+    "i": {
+        "x": [
+            0.667
+        ],
+        "y": [
+            1
+        ]
+    }
+}
+
+

Here is the second keyframe, t is 60 which is the half way point of the animation.

+

You can compare s with the previous keyframe to see how the position is affected.

+

In this case it went from [235, 106] to [235, 441], meaning the ball has moved down.

+

i and o are set up for an "ease out" curve, meaning the animation starts quick +but eventually it slows down.

+

Last Keyframe

+
{
+    "t": 120,
+    "s": [
+        235,
+        106
+    ]
+}
+
+

The last keyframe is at the end of the animation (t is 100).

+

It doesn't have easing information because there are no more keyframes after this.

+

The value of s is the same as in the first keyframe, this allows for a seamless loop.

+

Animated scale

+
{
+    "a": 1,
+    "k": [
+        {
+            "t": 55,
+            "s": [
+                100,
+                100
+            ],
+            "h": 0,
+            "o": {
+                "x": [
+                    0
+                ],
+                "y": [
+                    0
+                ]
+            },
+            "i": {
+                "x": [
+                    1
+                ],
+                "y": [
+                    1
+                ]
+            }
+        },
+        {
+            "t": 60,
+            "s": [
+                136,
+                59
+            ],
+            "h": 0,
+            "o": {
+                "x": [
+                    0
+                ],
+                "y": [
+                    0
+                ]
+            },
+            "i": {
+                "x": [
+                    1
+                ],
+                "y": [
+                    1
+                ]
+            }
+        },
+        {
+            "t": 65,
+            "s": [
+                100,
+                100
+            ]
+        }
+    ]
+}
+
+

This provides the "squishing" effect. The works the same as the animated position described above.

+

One thing to note is the first and last keyframe have t that doesn't match with the ip and op of the animation.

+

This mean the property will maintain its value on the time before the first keyframe and after the last one.

+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/breakdown/images/builder/adding_shapes.png b/breakdown/images/builder/adding_shapes.png new file mode 100644 index 00000000..dfae92f1 Binary files /dev/null and b/breakdown/images/builder/adding_shapes.png differ diff --git a/breakdown/images/builder/adding_shapes.xml b/breakdown/images/builder/adding_shapes.xml new file mode 100644 index 00000000..74bed89e --- /dev/null +++ b/breakdown/images/builder/adding_shapes.xml @@ -0,0 +1 @@ +60060512512FALSE4FALSEFALSEFALSE0600FALSEFALSEFALSEsr00100005FALSEfl100#000000000FALSEst1001#000000000 diff --git a/breakdown/images/builder/animation.png b/breakdown/images/builder/animation.png new file mode 100644 index 00000000..30459b18 Binary files /dev/null and b/breakdown/images/builder/animation.png differ diff --git a/breakdown/images/builder/animation.xml b/breakdown/images/builder/animation.xml new file mode 100644 index 00000000..85bea927 --- /dev/null +++ b/breakdown/images/builder/animation.xml @@ -0,0 +1 @@ +60060512512FALSE4FALSEFALSEFALSE0600FALSEFALSEFALSEsr1002562561002000000011060001172551000FALSEfl100#ffcc0010.80#ffcc0010.80FALSEst1001#000000000 diff --git a/breakdown/images/builder/animation_out_point.png b/breakdown/images/builder/animation_out_point.png new file mode 100644 index 00000000..f217f52f Binary files /dev/null and b/breakdown/images/builder/animation_out_point.png differ diff --git a/breakdown/images/builder/basic_properties.xml b/breakdown/images/builder/basic_properties.xml new file mode 100644 index 00000000..d71ac786 --- /dev/null +++ b/breakdown/images/builder/basic_properties.xml @@ -0,0 +1 @@ +60060512512FALSE4FALSEFALSEFALSE0600FALSEFALSEFALSEsr00256256100200005FALSEfl100#ffcc0010.80#ffcc0010.80FALSEst1001#000000000 diff --git a/breakdown/images/builder/final.xml b/breakdown/images/builder/final.xml new file mode 100644 index 00000000..a4f1f0ea --- /dev/null +++ b/breakdown/images/builder/final.xml @@ -0,0 +1 @@ +600120512512FALSE4FALSEFALSEFALSE01200FALSEFALSEFALSEsr10025625610020000000110120001172551000FALSEfl100#ffcc0010.80#ffcc0010.80FALSEst1001#000000000 diff --git a/breakdown/images/builder/layer_out_point.png b/breakdown/images/builder/layer_out_point.png new file mode 100644 index 00000000..bb7e7c79 Binary files /dev/null and b/breakdown/images/builder/layer_out_point.png differ diff --git a/breakdown/images/builder/more_props.png b/breakdown/images/builder/more_props.png new file mode 100644 index 00000000..bda04f1b Binary files /dev/null and b/breakdown/images/builder/more_props.png differ diff --git a/breakdown/images/builder/setting_up.png b/breakdown/images/builder/setting_up.png new file mode 100644 index 00000000..22df1ec5 Binary files /dev/null and b/breakdown/images/builder/setting_up.png differ diff --git a/breakdown/images/builder/setting_up.xml b/breakdown/images/builder/setting_up.xml new file mode 100644 index 00000000..d07bbb0f --- /dev/null +++ b/breakdown/images/builder/setting_up.xml @@ -0,0 +1 @@ +60060512512FALSE4FALSEFALSEFALSE0600FALSEFALSE diff --git a/breakdown/images/builder/shape_position.png b/breakdown/images/builder/shape_position.png new file mode 100644 index 00000000..c0a4d05b Binary files /dev/null and b/breakdown/images/builder/shape_position.png differ diff --git a/breakdown/images/builder/star.png b/breakdown/images/builder/star.png new file mode 100644 index 00000000..7daffe8f Binary files /dev/null and b/breakdown/images/builder/star.png differ diff --git a/breakdown/images/builder/star.xml b/breakdown/images/builder/star.xml new file mode 100644 index 00000000..4fda036b --- /dev/null +++ b/breakdown/images/builder/star.xml @@ -0,0 +1 @@ +60060512512FALSE4FALSEFALSEFALSE0600FALSEFALSEFALSEsr100256256100200000551000FALSEfl100#ffcc0010.80#ffcc0010.80FALSEst1001#000000000 diff --git a/breakdown/lottie_from_scratch/index.html b/breakdown/lottie_from_scratch/index.html new file mode 100644 index 00000000..96e9d5b2 --- /dev/null +++ b/breakdown/lottie_from_scratch/index.html @@ -0,0 +1,518 @@ + + + + + + + + + + + + + + Lottie from Scratch - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Lottie from Scratch

+

In this example, we'll build a simple Lottie animation from scratch.

+

Introducing the builder tool

+

The builder tool allows you to build lottie animations +from its JSON components using a more convenient interface than manually +editing the cryptic lottie JSON attributes.

+

You can click on the categories on the toolbar to the left of the builder interface +then drag and drop blocks into the workspace and see the effects.

+

To the right you have a preview of the animation and the corresponding JSON.

+

The rest of this guide will assume you are following along using the builder.

+

Most block can be right-clicked to bring up a context menu, and you can select +"Help" from that menu to go on the page that describes the object represented by that block.

+

Setting up

+

Ensure your workspace is empty, if it isn't click on the "Clear" button near the top-right.

+

Start by selecting the Animation block in the Animation category and dragging it to the workspace.

+

Then select a Shape Layer (from Layers) and drop it into the Layers slot of the Animation block.

+

Your workspace should look something like this:

+

Screenshot of the workspace

+

You might have noticed the block attached to the layer. +For simplicity all the common layer properties are in a separate block in the builder, +this allows you to duplicate those blocks to copy the settings across layers and +the block is collapsed by default to avoid cluttering the workspace.

+

View workspace at the end of this step

+

Adding Shapes

+

In order to show something, we need to add some shapes to the layer.

+

So let's add a Polystar, a Fill and a Stroke from the Shapes category.

+

Note that the order is important:

+

Screenshot of the workspace

+

This should result in a black pentagon showing in the corner.

+

View workspace at the end of this step

+

Basic Properties

+

We start by moving our shape in a more sensible position.

+

To do so, select Static Property and connect it to the "Position" of the Polystar, then connect a "x y" block to it. +Both these blocks are under "Properties".

+

You can now edit the values of x and y to move the pentagon.

+

For example, setting them both to 256 should move the shape to the center of the screen:

+

Screenshot of the workspace

+

You can do something similar to modify the size of the pentagon and the fill color, +of course you need to select the right block types from the properties toolbox.

+

Screenshot of the workspace

+

The color can be changed by manually updating the RGB components or by selecting +a color from the palette shown after clicking the color preview on the block.

+

View workspace at the end of this step

+

Making a Star

+

We can turn the pentagon into a star by changing the star type and filling in +some more properties:

+

Screenshot of the workspace

+

Note that while you can use just a number block for "Rotation", +using the angle block allows you to edit the angle in a more intuitive way. +You can tell these block apart because they are a different color and the +angle block shows the ° symbol.

+

View workspace at the end of this step

+

Animating the Star

+

Until now, we've only seen static properties, but now we can have a look at some +animated ones.

+

To animate the star rotation, we need to first disconnect the static property from it +and connect an animated property in its place.

+

Thne attach two keyframe blocks to the animated property.

+

Once the keyframes are added, attach angle blocks to their value slots and change the second keyframe to have a time of 60 and a value of 72°.

+

Screenshot of the workspace

+

You should now see the star spinning in the preview.

+

View workspace at the end of this step

+

Making the Animation longer

+

Currently, the animation lasts for 1 second (60 frames).

+

If you want it to last for longer, you need to first change the Out Point in the animation block. +Let's change it to 120 to make the animation last for 2 seconds.

+

Screenshot of the workspace

+

You'll see the star starts blinking, disappearing after a second and reappearing +after another second.

+

This is because we also need to update the layer Out Point.

+

By default, the layer properties are collapsed, so right-click on the Layer Properties +and select "Expand Block" from the context menu, then change its "Out Point" +to match with the Animation block.

+

Screenshot of the workspace

+

Now the star remains visible the whole time, but it stops rotating at the second mark. +To fix that you can update the second keyframe in the star rotation to have a time of 120. +Alternatively you can add a third keyframe with that time and an appropriate value.

+

View the final workspace

+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/breakdown/precomps/index.html b/breakdown/precomps/index.html new file mode 100644 index 00000000..b004c5b2 --- /dev/null +++ b/breakdown/precomps/index.html @@ -0,0 +1,981 @@ + + + + + + + + + + + + + + Precompositions - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Precompositions

+

This page will explain Precompositions (or precomps for short), +which are a defining feature of the Lottie format which allows for great +flexibility in effects and organization of animation files.

+

What are Precompositions?

+

In short, a precomposition is an animation embedded inside another +animation, of which you can control playback.

+

Once you have a precomposition, you can use layers to reference it +in various parts of the animation to avoid repeating elements.

+

How do Precompositions work in a Lottie?

+

The main object is the Precomposition Asset. +Its structure is very simple, just an asset identifier and a list of layers.

+

By itself a precomposition asset doesn't do much, it needs to be +referenced by a Precomposition Layer.

+

You can think of the precomp asset to be similar to a video asset, +and the layer plays back the animation defined by that asset.

+

Follows a simple example:

+

First we start with a file without precomps:

+

+

+
+
+
+
+ +
+

+

And the same animation but using a precomp:

+

+

+
+
+
+
+ +
+

+

Now let's have a look at how the JSON changed:

+

This is the original animation, nothing special about it:

+
{
+    "nm": "Animation",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "assets": [],
+    "layers": [
+        {
+            "nm": "Shape Layer",
+            "ty": 4,
+            "ind": 0,
+            "st": 0,
+            "ip": 0,
+            "op": 60,
+            "ks": {},
+            "shapes": [/* ... */]
+        }
+    ]
+}
+
+

And this is the version using a precomposition:

+
{
+    "nm": "Animation",
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "assets": [
+        {
+            "id": "Star",
+            "layers": [
+                {
+                    "nm": "Shape Layer",
+                    "ty": 4,
+                    "ind": 0,
+                    "st": 0,
+                    "ip": 0,
+                    "op": 60,
+                    "shapes": [/* ... */]
+                }
+            ]
+        }
+    ],
+    "layers": [
+        {
+            "nm": "Precomp Layer",
+            "refId": "Star"
+            "ty": 0,
+            "ind": 0,
+            "st": 0,
+            "ip": 0,
+            "op": 60,
+            "w": 512,
+            "h": 512,
+            "ks": {}
+        }
+    ],
+}
+
+

As you can see, the layers in the original animation have been moved to +an asset (in this example there was only one layer but it works the same +when you have multiple layer).

+

And in layers of the outer animation there is a single layer +referencing the new asset.

+

The structure of the asset is fairly +straightforward: a unique identifier (Star in the example) and the +list of layers in the precomposition.

+

The layer has the usual attributes +you can find on visual layers and a couple others: +refId is the identifier of the precomp the layer is referencing, +w and h define the clipping rectangle for the composition, in this +case they match the value in the outer animation.

+

Important things to note

+

A precomp doesn't contain assets, but it can reference assets defined in +the main animation object. It can also reference other precomps.

+

Layer indexes are unique in each composition: you can have a layer with +index 0 in multiple precomps and in the main animation, references +to these (such as when parenting layers) are relative to the composition.

+

You need to always specify w and h in the precomp layer or nothing +will be displayed.

+

What can you do with Precompositions?

+

In this section we'll describe some example use case including the +initial animations and the result to compare how a file needs to be +changed to obtain certain effects.

+

Resizing

+

If you need to resize an animation, the best way of doing it is by +precomposing all its layers and then scale the precomp layer.

+

While for simple examples you'd might be able to get away with scaling +all the layers in the original animation, it gets complicated if you +have parented layers or transforms applied to some of the layers.

+

Note that in the example below w and h keep their initial value +and only the scale is changed.

+
+ + + + + +
50
+
+
+
+
+ + +
+

Speeding up and Slowing down

+

Similarly, you can use time stretch to speed up and slow down an animation:

+
+ + + + + +
50
+
+
+
+
+ + +
+

You can also change the start time to delay the start of the precomp playback:

+
+ + + + + + + + + +
30
50
+
+
+
+
+ + +
+

Reversing Playback

+

While sr only allows you to speed up and slow down time, with +time remapping You can have more +interesting effects, such as reversing playback:

+
+
+
+
+
+
+ + +
+

Repeated Elements

+

Another important use for precomps is that they allow to have multiple +layers showing the same precomp.

+

In the following example the star is animated once but there are 8 +precomp layers with different rotations:

+

+

+
+
+
+
+ +
+

+

Overlaying Animations

+

Precomps also make it easier to combine multiple files into ones.

+

One thing to keep in mind is if the two files already have assets, +you need to ensure their asset identifier are unique, this can be done +by overwriting asset id and layer refId properties to some kind of +incremental values.

+

In the following example we will overlay the animation from the last +example with a different animation.

+

First Animation: +

+
+
+
+
+ +
+

+

Second Animation: +

+
+
+
+
+ +
+

+

Overlaid:

+
+
+
+
+
+
+ + +
+

If you look at the JSON you'll notice that this is how the structure changed:

+
// First Animation:
+{
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "assets": [
+        {
+            "id": "Star",
+            "layers": [ /* Star Precomp Layers */ ]
+        }
+    ],
+    "layers": [ /* First Animation Layers */ ]
+}
+
+// Second Animation
+{
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "assets": [],
+    "layers": [ /* Second Animation Layers */ ]
+}
+
+// Overlaid
+{
+    "ip": 0,
+    "op": 60,
+    "fr": 60,
+    "w": 512,
+    "h": 512,
+    "assets": [
+        {
+            "id": "Star",
+            "layers": [ /* Star Precomp Layers */ ]
+        },
+        {
+            "id": "Expanding Stars",
+            "layers": [ /* First Animation Layers */ ]
+        },
+        {
+            "id": "Circle",
+            "layers": [ /* Second Animation Layers */ ]
+        }
+    ],
+    "layers": [
+        {
+            "nm": "Expanding Stars Layer",
+            "refId": "Expanding Stars",
+            "ty": 0,
+            "st": 0,
+            "ip": 0,
+            "op": 60,
+            "w": 512,
+            "h": 512,
+            "ks": {}
+        },
+        {
+            "nm": "Circle Layer",
+            "refId": "Circle",
+            "ty": 0,
+            "st": 0,
+            "ip": 0,
+            "op": 60,
+            "w": 512,
+            "h": 512,
+            "ks": {}
+        }
+    ]
+}
+
+

In this example the two animations had the same duration and size, +you can use the techniques described earlier to resize or retime the +animations if you want to overlay animations with different sizes or +durations.

+

Concatenating Animations

+

This works basically the same as overlaying them, just by changing +some timing properties in the precomp layers.

+
+
+
+
+
+
+ + +
+

Masking Animations

+

Just like any other visual layer, precomp layers can be used for mattes.

+
+
+
+
+
+
+ + +
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compat/index.html b/compat/index.html new file mode 100644 index 00000000..b150f51e --- /dev/null +++ b/compat/index.html @@ -0,0 +1,475 @@ + + + + + + + + + + + + + + Compatibility with older versions - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Compatibility with older versions

+

This page describes breaking changes that have been introduced over time.

+

You'd need to check v from Animation to see the +the lottie is so old to need to worry about these.

+

The code examples are just for illustrative purposes and are not to be +taken as a complete conversion code.

+

[0,255] Colors

+

Until v 4.1.9.

+

Modern Lotties have color components in the [0, 1] range. +Older ones have components in the [0, 255] range.

+

Fix: Divide all color components by 255.

+

Static text document

+

Until v 4.4.14.

+

In Text Data , d was not animated.

+

Fix: Wrap into an animated property

+

text_layer.t.d = {"a": 0, "k": text_layer.t.d}

+

Shape closing

+

Until v 4.4.18.

+

Path objects had a boolean closed property and c was not +present in the bezier data.

+

Similarly, Mask had cl that worked the same way.

+

Fix: For each Path , update all the keyframes +(or the non-animated value) of ks. +Do the same to fix pt in each Mask .

+

shape.ks.k.c = shape.closed ? 1 : 0

+

Old keyframe style

+

Until v 5.0.0 (?).

+

Keyframes had an e property that specified +the end value for that keyframe (s marking the start value), +and the last keyframe would not have s.

+

Fix: Ignore all the e in keyframes, but copy the e from the keyframe +before last into the last keyframe.

+

keyframes[keyframes.length - 1].s = keyframes[keyframes.length - 2].e

+

Static text layer properties

+

Until v 5.7.15.

+

In Text Follow Path properties r, a, and p were +plain numbers instead of animated properties.

+

Fix: Wrap all of those into animated properties

+

text_layer.t.p.a + {"a": 0, "k": text_layer.t.p.a}

+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/concepts/index.html b/concepts/index.html new file mode 100644 index 00000000..17d26c47 --- /dev/null +++ b/concepts/index.html @@ -0,0 +1,991 @@ + + + + + + + + + + + + + + General concepts - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

General concepts

+

This page describes values and other objects used throughout the lottie format

+

Booleans

+

In some places boolean values are shown as booleans in the JSON (true/false). +In other places they are shown as integers with 0 or 1 as values.

+

Colors

+

Colors are represented as arrays with values between 0 and 1 for the RGB components.

+

for example:

+
    +
  • [1, 0, 0]
  • +
  • [1, 0.5, 0]
  • +
+

Note sometimes you might find color values with 4 components (the 4th being alpha) +but most player ignore the last component.

+

Gradients

+

Gradients are represented as a flat array, showing offsets and RGB components.

+

There are two possible representations, with alpha, and without.

+

Gradients without transparency

+

The array is a sequence of offset, red, green, blue components for each +color. all values are between 0 and 1

+

So let's say you want these colors:

+
    +
  • [0.161, 0.184, 0.459]
  • +
  • [0.196, 0.314, 0.69]
  • +
  • [0.769, 0.851, 0.961]
  • +
+

the array will look like the following:

+

[0, 0.161, 0.184, 0.459, 0.5, 0.196, 0.314, 0.69, 1, 0.769, 0.851, 0.961]

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription
0Offset of the 1st color (0 means at the start)
0.161Red component for the 1st color
0.184Green component for the 1st color
0.459Blue component for the 1st color
0.5Offset of the 2nd color (0.5 means half way)
0.196Red component for the 2nd color
0.314Green component for the 2nd color
0.69Blue component for the 2nd color
1Offset of the 3rd color (1 means at the end)
0.769Red component for the 3rd color
0.851Green component for the 3rd color
0.961Blue component for the 3rd color
+

Gradients with transparency

+

Alpha is added at the end, repeating offsets and followed by alpha for each colors

+

So assume the same colors as before, but opacity of 80% for the first color and 100% for the other two.

+

The array will look like this:

+

[0, 0.161, 0.184, 0.459, 0.5, 0.196, 0.314, 0.69, 1, 0.769, 0.851, 0.961, 0, 0.8, 0.5, 1, 1, 1]

+

It's the same array as the case without transparency but with the following values added at the end:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription
0Offset of the 1st color (0 means at the start)
0.8Alpha component for the 1st color
0.5Offset of the 2nd color (0.5 means half way)
1Alpha component for the 2nd color
1Offset of the 3rd color (1 means at the end)
1Alpha component for the 3rd color
+

Gradient Example

+
+
+ + +
+

Lists of layers and shapes

+

Such lists appear Precomposition, Animation, ShapeLayer, and Grop.

+

In such lists, items coming first will be rendered on top

+

So if you have for example: [Ellipse, Rectangle]

+

The ellipse will show on top of the rectangle:

+

+

+
+
+
+
+ +
+

+

This means the render order goes from the last element to the first.

+

Animated Property

+

Animated properties have two attributes

+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription View Schema
a0-1 intWhether the property is animated. Note some old animations might not have this
kValue or keyframes, this changes based on the value of a
+

If a is 0, then k just has the value of the property.

+

If a is 1, k will be an array of keyframes.

+

Keyframe

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription View Schema
tnumberKeyframe time (in frames)
sDepends on the propertyValue, note that scalar values have the value is wrapped in an array
i,oEasing Handle
h0-1 intWhether it's a hold frame
+

If h is present and it's 1, you don't need i and o, as the property will keep the same value +until the next keyframe.

+

Easing Handles

+

They are objects with x and y attributes, which are numbers within 0 and 1.

+

For multi-dimensional animated properties, these are arrays, with one element +per dimension so you can have different easing curves per dimension.

+

They represent a cubic bezier, starting at [0,0] and ending at [1,1] where +the value determines the easing function.

+

The x axis represents time, a value of 0 is the time of the current keyframe, +a value of 1 is the time of the next keyframe.

+

The y axis represents the value interpolation factor, a value of 0 +represents the value at the current keyframe, a value of 1 represents the +value at the next keyframe.

+

When you use easing you have two easing handles for the keyframe:

+

o is the "out" handle, and is the first one in the bezier, determines the curve +as it exits the current keyframe.

+

i is the "in" handle, and it's the second one in the bezier, determines the curve +as it enters the next keyframe.

+

For linear interpolation you'd have

+
{
+    "o": {"x": [0, 0], "y": [0, 0]},
+    "i": {"x": [1, 1], "y": [1, 1]}
+}
+
+

For easing in and out, you move the x towards the center, this makes the animation more fluid:

+
{
+    "o": {"x": [0.333, 0.333], "y": [0, 0]},
+    "i": {"x": [0.667, 0.667], "y": [1, 1]}
+}
+
+

Old Lottie Keyframes

+

Old lotties have an additional attribute for keyframes, e which works +similarly to s but represents the value at the end of the keyframe.

+

They also have a final keyframe with only the t attribute and you +need to determine its value based on the s value of the previous keyframe.

+

Easing example

+

In the following example, the ball moves left and right, on the background +you can see a representation of its easing function.

+
+
+ + +
+

Animated Position

+

Position properties have additional attributes in their keyframes to represent bezier tangents in the path followed by the animation

+
+

Also has the attributes from Keyframe.

+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tiarray of number +

Tangent for values (eg: moving position around a curved path)

+
toarray of number +

Tangent for values (eg: moving position around a curved path)

+
+
+

Transform

+

This represents a layer or shape transform.

+

It has the properties from Visual Object and its own properties are all animated:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeNameDescription View Schema
a2D VectorAnchor pointPosition (relative to its parent) around which transformations are applied (ie: center for rotation / scale)
p2D VectorPositionPosition / Translation
s2D VectorScaleScale factor, 100 for no scaling
rnumberRotationRotation in degrees, clockwise
sknumberSkewSkew amount as an angle in degrees
sanumberSkew AxisDirection at which skew is applied, in degrees (0 skews along the X axis, 90 along the Y axis)
onumberOpacityOpacity, 100 for fully opaque
+

To make the anchor point properly line up with the center of location, p and a should have the same value.

+

This example allows you to tweak transform attributes and see how the shape changes.

+

The anchor point is highlighted with an orange dot.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
256
256
256
256
100
100
0
0
0
100
+
+
+
+
+ + +
+

Split vector

+

Sometimes p might be split into separate components animated independently and have the following structure

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
sboolean = True +

Split

+
xAnimated number +

X

+
yAnimated number +

Y

+
zAnimated number +

Z

+
+
+

Bezier

+

This represents a cubic bezier path.

+

Note that for interpolation to work correctly all bezier values in a property's keyframe must have the same number of points.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeNameDescription View Schema
c0-1 intClosedWhether the bezier forms a closed loop
varray of 2D VectorVerticesPoints along the curve
iarray of 2D VectorIn TangentsCubic control points, incoming tangent
oarray of 2D VectorOut TangentsCubic control points, outgoing tangent
+

i and o are relative to v.

+

The nth bezier segment is defined as:

+
v[n], v[n]+o[n], v[n+1]+i[n+1], v[n+1]
+
+

If the bezier is closed, you need an extra segment going from the last point to the first, still following i and o appropriately.

+

If you want linear bezier, you can have i and o for a segment to be [0, 0]. +If you want it quadratic, set them to 2/3rd of what the quadratic control point would be.

+

If you want a point to be smooth you need to make sure that i = -o.

+
+
+ + +
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/constants/index.html b/constants/index.html new file mode 100644 index 00000000..0877e2a4 --- /dev/null +++ b/constants/index.html @@ -0,0 +1,1122 @@ + + + + + + + + + + + + + + Enumerations - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Enumerations

+

Blend Mode

+

Layer and shape blend mode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
0Normal
1Multiply
2Screen
3Overlay
4Darken
5Lighten
6Color Dodge
7Color Burn
8Hard Light
9Soft Light
10Difference
11Exclusion
12Hue
13Saturation
14Color
15Luminosity
16Add
17Hard Mix
+

In the following example you can change the blend mode of the top layer

+
+ + + + + + + + + +
50
+
+
+
+
+ +
+

Composite

+

How to stack copies in a repeater

+ + + + + + + + + + + + + + + + + + + + +
ValueNameDescriptionView Schema
1BelowSubsequent copies are added underneath the previous ones.
2AboveSubsequent copies are added on top of the previous ones.
+

Fill Rule

+

Rule used to handle multiple shapes rendered with the same fill object

+ + + + + + + + + + + + + + + + + + + + +
ValueNameDescriptionView Schema
1Non ZeroEverything is colored (You can think of this as an OR)
2Even OddColored based on intersections and path direction, can be used to create "holes"
+

Font Path Origin

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
0Local
1Css Url
2Script Url
3Font Url
+

Gradient Type

+

Type of a gradient

+ + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Linear
2Radial
+

Line Cap

+

Style at the end of a stoked line

+ + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Butt
2Round
3Square
+

Line Join

+

Style at a sharp corner of a stoked line

+ + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Miter
2Round
3Bevel
+

Mask Mode

+

How masks interact with each other. See https://helpx.adobe.com/after-effects/using/alpha-channels-masks-mattes.html

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
'n'None
'a'Add
's'Subtract
'i'Intersect
'l'Lighten
'd'Darken
'f'Difference
+

Matte Mode

+

How a layer should mask another layer

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
0Normal
1Alpha
2Inverted Alpha
3Luma
4Inverted Luma
+
+ + + + + +
+
+
+
+
+ +
+

Merge Mode

+

Boolean operation on shapes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Normal
2Add
3Subtract
4Intersect
5Exclude Intersections
+

Shape Direction

+

Drawing direction of the shape curve, useful for trim path

+ + + + + + + + + + + + + + + + + + + + +
ValueNameDescriptionView Schema
1NormalUsually clockwise
3ReversedUsually counter clockwise
+

Star Type

+

Star or Polygon

+ + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Star
2Polygon
+

Stroke Dash Type

+

Type of a dash item in a stroked line

+ + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
'd'Dash
'g'Gap
'o'Offset
+

Text Based

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Characters
2Character Excluding Spaces
3Words
4Lines
+

Text Grouping

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Characters
2Word
3Line
4All
+

Text Justify

+

Text alignment / justification

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
0Left
1Right
2Center
3Justify with Last Line Left
4Justify with Last Line Right
5Justify with Last Line Center
6Justify with Last Line Full
+

Text Shape

+

Defines the function used to determine the interpolating factor on a text range selector.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Square
2Ramp Up
3Ramp Down
4Triangle
5Round
6Smooth
+

To better illustrate what the value mean, the graphics below shows an +example for each value, including the function itself, based on the +range start and end character.

+

Text Shapes

+

Trim Multiple Shapes

+

How to handle multiple shapes in trim path

+ + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Simultaneously
2Individually
+

Text Caps

+

+ + + + + + + + + + + + + + + + + + + + + +
ValueNameView Schema
0Regular
1All Caps
2Small Caps
+

Text Range Units

+

Unit type for a text selector

+ + + + + + + + + + + + + + + + + +
ValueNameView Schema
1Percent
2Index
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/css/base.css b/css/base.css new file mode 100644 index 00000000..2d684824 --- /dev/null +++ b/css/base.css @@ -0,0 +1,289 @@ +html { + scroll-padding-top: 70px; +} + +body { + padding-top: 70px; +} + +p > img { + max-width: 100%; + height: auto; +} + +ul.nav li.first-level { + font-weight: bold; +} + +ul.nav li.third-level { + padding-left: 12px; +} + +div.col-md-3 { + padding-left: 0; +} + +div.col-md-9 { + padding-bottom: 100px; +} + +div.source-links { + float: right; +} + +/* + * Side navigation + * + * Scrollspy and affixed enhanced navigation to highlight sections and secondary + * sections of docs content. + */ + +/* By default it's not affixed in mobile views, so undo that */ +.bs-sidebar.affix { + position: static; +} + +.bs-sidebar.well { + padding: 0; +} + +/* First level of nav */ +.bs-sidenav { + margin-top: 30px; + margin-bottom: 30px; + padding-top: 10px; + padding-bottom: 10px; + border-radius: 5px; +} + +/* All levels of nav */ +.bs-sidebar .nav > li > a { + display: block; + padding: 5px 20px; + z-index: 1; +} +.bs-sidebar .nav > li > a:hover, +.bs-sidebar .nav > li > a:focus { + text-decoration: none; + border-right: 1px solid; +} +.bs-sidebar .nav > .active > a, +.bs-sidebar .nav > .active:hover > a, +.bs-sidebar .nav > .active:focus > a { + font-weight: bold; + background-color: transparent; + border-right: 1px solid; +} + +/* Nav: second level (shown on .active) */ +.bs-sidebar .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + margin-bottom: 8px; +} +.bs-sidebar .nav .nav > li > a { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 30px; + font-size: 90%; +} + +/* Show and affix the side nav when space allows it */ +@media (min-width: 992px) { + .bs-sidebar .nav > .active > ul { + display: block; + } + /* Widen the fixed sidebar */ + .bs-sidebar.affix, + .bs-sidebar.affix-bottom { + width: 213px; + } + .bs-sidebar.affix { + position: fixed; /* Undo the static from mobile first approach */ + top: 80px; + max-height: calc(100% - 180px); + overflow-y: auto; + } + .bs-sidebar.affix-bottom { + position: absolute; /* Undo the static from mobile first approach */ + } + .bs-sidebar.affix-bottom .bs-sidenav, + .bs-sidebar.affix .bs-sidenav { + margin-top: 0; + margin-bottom: 0; + } +} +@media (min-width: 1200px) { + /* Widen the fixed sidebar again */ + .bs-sidebar.affix-bottom, + .bs-sidebar.affix { + width: 263px; + } +} + + +/* Added to support >2 level nav in drop down */ + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu>.dropdown-menu { + top: 0; + left: 100%; + margin-top: 0px; + margin-left: 0px; +} + +.dropdown-submenu:hover>.dropdown-menu { + display: block; +} + +.dropdown-submenu>a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #ccc; + margin-top: 5px; + margin-right: -10px; +} + +.dropdown-submenu:hover>a:after { + border-left-color: #fff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left>.dropdown-menu { + left: -100%; + margin-left: 00px; +} +/* Start Bootstrap Callouts CSS Source by Chris Pratt (https://codepen.io/chrisdpratt/pen/IAymB) MIT License*/ +.bs-callout { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; + background-color: #FCFDFF; +} +.bs-callout h4 { + font-style: normal; + font-weight: 400; + margin-top: 0; + margin-bottom: 5px; +} +.bs-callout p:last-child { + margin-bottom: 0; +} +.bs-callout code { + border-radius: 3px; +} +.bs-callout+.bs-callout { + margin-top: -5px; +} +.bs-callout-default { + border-left-color: #FA023C; /*modified from upstream default by Christopher Simpkins*/ +} +.bs-callout-default h4 { + color: #FA023C; /*modified from upstream default by Christopher Simpkins*/ +} +.bs-callout-primary { + border-left-color: #428bca; +} +.bs-callout-primary h4 { + color: #428bca; +} +.bs-callout-success { + border-left-color: #5cb85c; +} +.bs-callout-success h4 { + color: #5cb85c; +} +.bs-callout-danger { + border-left-color: #d9534f; +} +.bs-callout-danger h4 { + color: #d9534f; +} +.bs-callout-warning { + border-left-color: #f0ad4e; +} +.bs-callout-warning h4 { + color: #f0ad4e; +} +.bs-callout-info { + border-left-color: #5bc0de; +} +.bs-callout-info h4 { + color: #5bc0de; +} +/* End Bootstrap Callouts CSS Source by Chris Pratt */ + +/* Headerlinks */ +.headerlink { + display: none; + padding-left: .5em; +} + +h1:hover .headerlink, h2:hover .headerlink, h3:hover .headerlink, h4:hover .headerlink, h5:hover .headerlink, h6:hover .headerlink { + display: inline-block; +} + +/* Admonitions */ +.admonition { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; + background-color: #FCFDFF; +} + +.admonition p:last-child { + margin-bottom: 0; +} +.admonition code { + border-radius: 3px; +} +.admonition+.admonition { + margin-top: -5px; +} + +.admonition.note { /* csslint allow: adjoining-classes */ + border-left-color: #428bca; +} + +.admonition.warning { /* csslint allow: adjoining-classes */ + border-left-color: #f0ad4e; +} + +.admonition.danger { /* csslint allow: adjoining-classes */ + border-left-color: #d9534f; +} + +.admonition-title { + font-size: 19px; + font-style: normal; + font-weight: 400; + margin-top: 0; + margin-bottom: 5px; +} + +.admonition.note > .admonition-title { + color: #428bca; +} + +.admonition.warning > .admonition-title { + color: #f0ad4e; +} + +.admonition.danger > .admonition-title { + color: #d9534f; +} diff --git a/css/base.min.css b/css/base.min.css new file mode 100644 index 00000000..f7e580f2 --- /dev/null +++ b/css/base.min.css @@ -0,0 +1 @@ +html{scroll-padding-top:70px}body{padding-top:70px}p>img{max-width:100%;height:auto}ul.nav li.first-level{font-weight:bold}ul.nav li.third-level{padding-left:12px}div.col-md-3{padding-left:0}div.col-md-9{padding-bottom:100px}div.source-links{float:right}.bs-sidebar.affix{position:static}.bs-sidebar.well{padding:0}.bs-sidenav{margin-top:30px;margin-bottom:30px;padding-top:10px;padding-bottom:10px;border-radius:5px}.bs-sidebar .nav>li>a{display:block;padding:5px 20px;z-index:1}.bs-sidebar .nav>li>a:hover,.bs-sidebar .nav>li>a:focus{text-decoration:none;border-right:1px solid}.bs-sidebar .nav>.active>a,.bs-sidebar .nav>.active:hover>a,.bs-sidebar .nav>.active:focus>a{font-weight:bold;background-color:transparent;border-right:1px solid}.bs-sidebar .nav .nav{display:none;margin-bottom:8px}.bs-sidebar .nav .nav>li>a{padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%}@media(min-width:992px){.bs-sidebar .nav>.active>ul{display:block}.bs-sidebar.affix,.bs-sidebar.affix-bottom{width:213px}.bs-sidebar.affix{position:fixed;top:80px;max-height:calc(100% - 180px);overflow-y:auto}.bs-sidebar.affix-bottom{position:absolute}.bs-sidebar.affix-bottom .bs-sidenav,.bs-sidebar.affix .bs-sidenav{margin-top:0;margin-bottom:0}}@media(min-width:1200px){.bs-sidebar.affix-bottom,.bs-sidebar.affix{width:263px}}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:0;margin-left:0}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:00px}.bs-callout{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px;background-color:#fcfdff}.bs-callout h4{font-style:normal;font-weight:400;margin-top:0;margin-bottom:5px}.bs-callout p:last-child{margin-bottom:0}.bs-callout code{border-radius:3px}.bs-callout+.bs-callout{margin-top:-5px}.bs-callout-default{border-left-color:#fa023c}.bs-callout-default h4{color:#fa023c}.bs-callout-primary{border-left-color:#428bca}.bs-callout-primary h4{color:#428bca}.bs-callout-success{border-left-color:#5cb85c}.bs-callout-success h4{color:#5cb85c}.bs-callout-danger{border-left-color:#d9534f}.bs-callout-danger h4{color:#d9534f}.bs-callout-warning{border-left-color:#f0ad4e}.bs-callout-warning h4{color:#f0ad4e}.bs-callout-info{border-left-color:#5bc0de}.bs-callout-info h4{color:#5bc0de}.headerlink{display:none;padding-left:.5em}h1:hover .headerlink,h2:hover .headerlink,h3:hover .headerlink,h4:hover .headerlink,h5:hover .headerlink,h6:hover .headerlink{display:inline-block}.admonition{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px;background-color:#fcfdff}.admonition p:last-child{margin-bottom:0}.admonition code{border-radius:3px}.admonition+.admonition{margin-top:-5px}.admonition.note{border-left-color:#428bca}.admonition.warning{border-left-color:#f0ad4e}.admonition.danger{border-left-color:#d9534f}.admonition-title{font-size:19px;font-style:normal;font-weight:400;margin-top:0;margin-bottom:5px}.admonition.note>.admonition-title{color:#428bca}.admonition.warning>.admonition-title{color:#f0ad4e}.admonition.danger>.admonition-title{color:#d9534f} diff --git a/css/bootstrap-custom.css b/css/bootstrap-custom.css new file mode 100644 index 00000000..631252d2 --- /dev/null +++ b/css/bootstrap-custom.css @@ -0,0 +1,5309 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block; +} +audio, canvas, video { + display: inline-block; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], template { + display: none; +} +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%} +body { + margin: 0; +} +a { + background: transparent; +} +a:focus { + outline: thin dotted; +} +a:active, a:hover { + outline: 0; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +mark { + color: #000; + background: #ff0; +} +code, kbd, pre, samp { + font-family: Hack, monospace, serif; + font-size: 1em; +} +pre { + white-space: pre-wrap; +} +q { + quotes: "\201C" "\201D" "\2018" "\2019"} +small { + font-size: 80%} +sub, sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 0; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +button, input, select, textarea { + margin: 0; + font-family: inherit; + font-size: 100%} +button, input { + line-height: normal; +} +button, select { + text-transform: none; +} +button, html input[type="button"], input[type="reset"], input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +button[disabled], html input[disabled] { + cursor: default; +} +input[type="checkbox"], input[type="radio"] { + padding: 0; + box-sizing: border-box; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +button::-moz-focus-inner, input::-moz-focus-inner { + padding: 0; + border: 0; +} +textarea { + overflow: auto; + vertical-align: top; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +@media print { + * { + color: #000!important; + text-shadow: none!important; + background: transparent!important; + box-shadow: none!important; +} +a, a:visited { + text-decoration: underline; +} +a[href]:after { + content: " (" attr(href) ")"} +abbr[title]:after { + content: " (" attr(title) ")"} +a[href^="javascript:"]:after, a[href^="#"]:after { + content: ""} +pre, blockquote { + border: 1px solid #999; + page-break-inside: avoid; +} +thead { + display: table-header-group; +} +tr, img { + page-break-inside: avoid; +} +img { + max-width: 100%!important; +} +@page { + margin: 2cm .5cm; +} +p, h2, h3 { + orphans: 3; + widows: 3; +} +h2, h3 { + page-break-after: avoid; +} +select { + background: #fff!important; +} +.navbar { + display: none; +} +.table td, .table th { + background-color: #fff!important; +} +.btn>.caret, .dropup>.btn>.caret { + border-top-color: #000!important; +} +.label { + border: 1px solid #000; +} +.table { + border-collapse: collapse!important; +} +.table-bordered th, .table-bordered td { + border: 1px solid #ddd!important; +} +}*, *:before, *:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 62.5%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: Merriweather, Georgia, serif; + font-size: 14px; + line-height: 1.428571429; + color: #222; + background-color: #fff; +} +input, button, select, textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #008cba; + text-decoration: none; +} +a:hover, a:focus { + color: #00526e; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +img { + vertical-align: middle; +} +.img-responsive { + display: block; + height: auto; + max-width: 100%} +.img-rounded { + border-radius: 0; +} +.img-thumbnail { + display: inline-block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%} +hr { + margin-top: 21px; + margin-bottom: 21px; + border: 0; + border-top: 1px solid #ddd; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + line-height: 1.1; + color: inherit; +} +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + font-weight: normal; + line-height: 1; + color: #999; +} +h1, h2, h3 { + margin-top: 21px; + margin-bottom: 10.5px; +} +h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small { + font-size: 65%} +h4, h5, h6 { + margin-top: 10.5px; + margin-bottom: 10.5px; +} +h4 small, h5 small, h6 small, h4 .small, h5 .small, h6 .small { + font-size: 75%} +h1, .h1 { + font-size: 39px; +} +h2, .h2 { + font-size: 32px; +} +h3, .h3 { + font-size: 26px; +} +h4, .h4 { + font-size: 19px; +} +h5, .h5 { + font-size: 15px; +} +h6, .h6 { + font-size: 13px; +} +p { + margin: 0 0 10.5px; +} +.lead { + margin-bottom: 21px; + font-size: 17px; + font-weight: 200; + line-height: 1.4; +} +@media(min-width:768px) { + .lead { + font-size: 22.5px; +} +}small, .small { + font-size: 85%} +cite { + font-style: normal; +} +.text-muted { + color: #999; +} +.text-primary { + color: #008cba; +} +.text-primary:hover { + color: #006687; +} +.text-warning { + color: #e99002; +} +.text-warning:hover { + color: #b67102; +} +.text-danger { + color: #f04124; +} +.text-danger:hover { + color: #d32a0e; +} +.text-success { + color: #43ac6a; +} +.text-success:hover { + color: #358753; +} +.text-info { + color: #5bc0de; +} +.text-info:hover { + color: #31b0d5; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.page-header { + padding-bottom: 9.5px; + margin: 42px 0 21px; + border-bottom: 1px solid #ddd; +} +ul, ol { + margin-top: 0; + margin-bottom: 10.5px; +} +ul ul, ol ul, ul ol, ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; +} +.list-inline>li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +.list-inline>li:first-child { + padding-left: 0; +} +dl { + margin-top: 0; + margin-bottom: 21px; +} +dt, dd { + line-height: 1.428571429; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media(min-width:768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 180px; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +}abbr[title], abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10.5px 21px; + margin: 0 0 21px; + border-left: 5px solid #ddd; +} +blockquote p { + font-size: 18.75px; + font-weight: 300; + line-height: 1.25; +} +blockquote p:last-child { + margin-bottom: 0; +} +blockquote small, blockquote .small { + display: block; + line-height: 1.428571429; + color: #6f6f6f; +} +blockquote small:before, blockquote .small:before { + content: '\2014 \00A0'} +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #ddd; + border-left: 0; +} +blockquote.pull-right p, blockquote.pull-right small, blockquote.pull-right .small { + text-align: right; +} +blockquote.pull-right small:before, blockquote.pull-right .small:before { + content: ''} +blockquote.pull-right small:after, blockquote.pull-right .small:after { + content: '\00A0 \2014'} +blockquote:before, blockquote:after { + content: ""} +address { + margin-bottom: 21px; + font-style: normal; + line-height: 1.428571429; +} +code, kbd, pre, samp { + font-family: Hack, Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 0; +} +pre { + display: block; + padding: 10px; + margin: 0 0 10.5px; + font-size: 14px; + line-height: 1.428571429; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 0; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +@media(min-width:768px) { + .container { + width: 750px; +} +}@media(min-width:992px) { + .container { + width: 970px; +} +}@media(min-width:1200px) { + .container { + width: 1170px; +} +}.row { + margin-right: -15px; + margin-left: -15px; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%} +.col-xs-11 { + width: 91.66666666666666%} +.col-xs-10 { + width: 83.33333333333334%} +.col-xs-9 { + width: 75%} +.col-xs-8 { + width: 66.66666666666666%} +.col-xs-7 { + width: 58.333333333333336%} +.col-xs-6 { + width: 50%} +.col-xs-5 { + width: 41.66666666666667%} +.col-xs-4 { + width: 33.33333333333333%} +.col-xs-3 { + width: 25%} +.col-xs-2 { + width: 16.666666666666664%} +.col-xs-1 { + width: 8.333333333333332%} +.col-xs-pull-12 { + right: 100%} +.col-xs-pull-11 { + right: 91.66666666666666%} +.col-xs-pull-10 { + right: 83.33333333333334%} +.col-xs-pull-9 { + right: 75%} +.col-xs-pull-8 { + right: 66.66666666666666%} +.col-xs-pull-7 { + right: 58.333333333333336%} +.col-xs-pull-6 { + right: 50%} +.col-xs-pull-5 { + right: 41.66666666666667%} +.col-xs-pull-4 { + right: 33.33333333333333%} +.col-xs-pull-3 { + right: 25%} +.col-xs-pull-2 { + right: 16.666666666666664%} +.col-xs-pull-1 { + right: 8.333333333333332%} +.col-xs-pull-0 { + right: 0; +} +.col-xs-push-12 { + left: 100%} +.col-xs-push-11 { + left: 91.66666666666666%} +.col-xs-push-10 { + left: 83.33333333333334%} +.col-xs-push-9 { + left: 75%} +.col-xs-push-8 { + left: 66.66666666666666%} +.col-xs-push-7 { + left: 58.333333333333336%} +.col-xs-push-6 { + left: 50%} +.col-xs-push-5 { + left: 41.66666666666667%} +.col-xs-push-4 { + left: 33.33333333333333%} +.col-xs-push-3 { + left: 25%} +.col-xs-push-2 { + left: 16.666666666666664%} +.col-xs-push-1 { + left: 8.333333333333332%} +.col-xs-push-0 { + left: 0; +} +.col-xs-offset-12 { + margin-left: 100%} +.col-xs-offset-11 { + margin-left: 91.66666666666666%} +.col-xs-offset-10 { + margin-left: 83.33333333333334%} +.col-xs-offset-9 { + margin-left: 75%} +.col-xs-offset-8 { + margin-left: 66.66666666666666%} +.col-xs-offset-7 { + margin-left: 58.333333333333336%} +.col-xs-offset-6 { + margin-left: 50%} +.col-xs-offset-5 { + margin-left: 41.66666666666667%} +.col-xs-offset-4 { + margin-left: 33.33333333333333%} +.col-xs-offset-3 { + margin-left: 25%} +.col-xs-offset-2 { + margin-left: 16.666666666666664%} +.col-xs-offset-1 { + margin-left: 8.333333333333332%} +.col-xs-offset-0 { + margin-left: 0; +} +@media(min-width:768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; +} +.col-sm-12 { + width: 100%} +.col-sm-11 { + width: 91.66666666666666%} +.col-sm-10 { + width: 83.33333333333334%} +.col-sm-9 { + width: 75%} +.col-sm-8 { + width: 66.66666666666666%} +.col-sm-7 { + width: 58.333333333333336%} +.col-sm-6 { + width: 50%} +.col-sm-5 { + width: 41.66666666666667%} +.col-sm-4 { + width: 33.33333333333333%} +.col-sm-3 { + width: 25%} +.col-sm-2 { + width: 16.666666666666664%} +.col-sm-1 { + width: 8.333333333333332%} +.col-sm-pull-12 { + right: 100%} +.col-sm-pull-11 { + right: 91.66666666666666%} +.col-sm-pull-10 { + right: 83.33333333333334%} +.col-sm-pull-9 { + right: 75%} +.col-sm-pull-8 { + right: 66.66666666666666%} +.col-sm-pull-7 { + right: 58.333333333333336%} +.col-sm-pull-6 { + right: 50%} +.col-sm-pull-5 { + right: 41.66666666666667%} +.col-sm-pull-4 { + right: 33.33333333333333%} +.col-sm-pull-3 { + right: 25%} +.col-sm-pull-2 { + right: 16.666666666666664%} +.col-sm-pull-1 { + right: 8.333333333333332%} +.col-sm-pull-0 { + right: 0; +} +.col-sm-push-12 { + left: 100%} +.col-sm-push-11 { + left: 91.66666666666666%} +.col-sm-push-10 { + left: 83.33333333333334%} +.col-sm-push-9 { + left: 75%} +.col-sm-push-8 { + left: 66.66666666666666%} +.col-sm-push-7 { + left: 58.333333333333336%} +.col-sm-push-6 { + left: 50%} +.col-sm-push-5 { + left: 41.66666666666667%} +.col-sm-push-4 { + left: 33.33333333333333%} +.col-sm-push-3 { + left: 25%} +.col-sm-push-2 { + left: 16.666666666666664%} +.col-sm-push-1 { + left: 8.333333333333332%} +.col-sm-push-0 { + left: 0; +} +.col-sm-offset-12 { + margin-left: 100%} +.col-sm-offset-11 { + margin-left: 91.66666666666666%} +.col-sm-offset-10 { + margin-left: 83.33333333333334%} +.col-sm-offset-9 { + margin-left: 75%} +.col-sm-offset-8 { + margin-left: 66.66666666666666%} +.col-sm-offset-7 { + margin-left: 58.333333333333336%} +.col-sm-offset-6 { + margin-left: 50%} +.col-sm-offset-5 { + margin-left: 41.66666666666667%} +.col-sm-offset-4 { + margin-left: 33.33333333333333%} +.col-sm-offset-3 { + margin-left: 25%} +.col-sm-offset-2 { + margin-left: 16.666666666666664%} +.col-sm-offset-1 { + margin-left: 8.333333333333332%} +.col-sm-offset-0 { + margin-left: 0; +} +}@media(min-width:992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; +} +.col-md-12 { + width: 100%} +.col-md-11 { + width: 91.66666666666666%} +.col-md-10 { + width: 83.33333333333334%} +.col-md-9 { + width: 75%} +.col-md-8 { + width: 66.66666666666666%} +.col-md-7 { + width: 58.333333333333336%} +.col-md-6 { + width: 50%} +.col-md-5 { + width: 41.66666666666667%} +.col-md-4 { + width: 33.33333333333333%} +.col-md-3 { + width: 25%} +.col-md-2 { + width: 16.666666666666664%} +.col-md-1 { + width: 8.333333333333332%} +.col-md-pull-12 { + right: 100%} +.col-md-pull-11 { + right: 91.66666666666666%} +.col-md-pull-10 { + right: 83.33333333333334%} +.col-md-pull-9 { + right: 75%} +.col-md-pull-8 { + right: 66.66666666666666%} +.col-md-pull-7 { + right: 58.333333333333336%} +.col-md-pull-6 { + right: 50%} +.col-md-pull-5 { + right: 41.66666666666667%} +.col-md-pull-4 { + right: 33.33333333333333%} +.col-md-pull-3 { + right: 25%} +.col-md-pull-2 { + right: 16.666666666666664%} +.col-md-pull-1 { + right: 8.333333333333332%} +.col-md-pull-0 { + right: 0; +} +.col-md-push-12 { + left: 100%} +.col-md-push-11 { + left: 91.66666666666666%} +.col-md-push-10 { + left: 83.33333333333334%} +.col-md-push-9 { + left: 75%} +.col-md-push-8 { + left: 66.66666666666666%} +.col-md-push-7 { + left: 58.333333333333336%} +.col-md-push-6 { + left: 50%} +.col-md-push-5 { + left: 41.66666666666667%} +.col-md-push-4 { + left: 33.33333333333333%} +.col-md-push-3 { + left: 25%} +.col-md-push-2 { + left: 16.666666666666664%} +.col-md-push-1 { + left: 8.333333333333332%} +.col-md-push-0 { + left: 0; +} +.col-md-offset-12 { + margin-left: 100%} +.col-md-offset-11 { + margin-left: 91.66666666666666%} +.col-md-offset-10 { + margin-left: 83.33333333333334%} +.col-md-offset-9 { + margin-left: 75%} +.col-md-offset-8 { + margin-left: 66.66666666666666%} +.col-md-offset-7 { + margin-left: 58.333333333333336%} +.col-md-offset-6 { + margin-left: 50%} +.col-md-offset-5 { + margin-left: 41.66666666666667%} +.col-md-offset-4 { + margin-left: 33.33333333333333%} +.col-md-offset-3 { + margin-left: 25%} +.col-md-offset-2 { + margin-left: 16.666666666666664%} +.col-md-offset-1 { + margin-left: 8.333333333333332%} +.col-md-offset-0 { + margin-left: 0; +} +}@media(min-width:1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; +} +.col-lg-12 { + width: 100%} +.col-lg-11 { + width: 91.66666666666666%} +.col-lg-10 { + width: 83.33333333333334%} +.col-lg-9 { + width: 75%} +.col-lg-8 { + width: 66.66666666666666%} +.col-lg-7 { + width: 58.333333333333336%} +.col-lg-6 { + width: 50%} +.col-lg-5 { + width: 41.66666666666667%} +.col-lg-4 { + width: 33.33333333333333%} +.col-lg-3 { + width: 25%} +.col-lg-2 { + width: 16.666666666666664%} +.col-lg-1 { + width: 8.333333333333332%} +.col-lg-pull-12 { + right: 100%} +.col-lg-pull-11 { + right: 91.66666666666666%} +.col-lg-pull-10 { + right: 83.33333333333334%} +.col-lg-pull-9 { + right: 75%} +.col-lg-pull-8 { + right: 66.66666666666666%} +.col-lg-pull-7 { + right: 58.333333333333336%} +.col-lg-pull-6 { + right: 50%} +.col-lg-pull-5 { + right: 41.66666666666667%} +.col-lg-pull-4 { + right: 33.33333333333333%} +.col-lg-pull-3 { + right: 25%} +.col-lg-pull-2 { + right: 16.666666666666664%} +.col-lg-pull-1 { + right: 8.333333333333332%} +.col-lg-pull-0 { + right: 0; +} +.col-lg-push-12 { + left: 100%} +.col-lg-push-11 { + left: 91.66666666666666%} +.col-lg-push-10 { + left: 83.33333333333334%} +.col-lg-push-9 { + left: 75%} +.col-lg-push-8 { + left: 66.66666666666666%} +.col-lg-push-7 { + left: 58.333333333333336%} +.col-lg-push-6 { + left: 50%} +.col-lg-push-5 { + left: 41.66666666666667%} +.col-lg-push-4 { + left: 33.33333333333333%} +.col-lg-push-3 { + left: 25%} +.col-lg-push-2 { + left: 16.666666666666664%} +.col-lg-push-1 { + left: 8.333333333333332%} +.col-lg-push-0 { + left: 0; +} +.col-lg-offset-12 { + margin-left: 100%} +.col-lg-offset-11 { + margin-left: 91.66666666666666%} +.col-lg-offset-10 { + margin-left: 83.33333333333334%} +.col-lg-offset-9 { + margin-left: 75%} +.col-lg-offset-8 { + margin-left: 66.66666666666666%} +.col-lg-offset-7 { + margin-left: 58.333333333333336%} +.col-lg-offset-6 { + margin-left: 50%} +.col-lg-offset-5 { + margin-left: 41.66666666666667%} +.col-lg-offset-4 { + margin-left: 33.33333333333333%} +.col-lg-offset-3 { + margin-left: 25%} +.col-lg-offset-2 { + margin-left: 16.666666666666664%} +.col-lg-offset-1 { + margin-left: 8.333333333333332%} +.col-lg-offset-0 { + margin-left: 0; +} +}table { + max-width: 100%; + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + margin-bottom: 21px; +} +.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table>thead>tr>th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table>caption+thead>tr:first-child>th, .table>colgroup+thead>tr:first-child>th, .table>thead:first-child>tr:first-child>th, .table>caption+thead>tr:first-child>td, .table>colgroup+thead>tr:first-child>td, .table>thead:first-child>tr:first-child>td { + border-top: 0; +} +.table>tbody+tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed>thead>tr>th, .table-condensed>tbody>tr>th, .table-condensed>tfoot>tr>th, .table-condensed>thead>tr>td, .table-condensed>tbody>tr>td, .table-condensed>tfoot>tr>td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered>thead>tr>th, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>tbody>tr>td, .table-bordered>tfoot>tr>td { + border: 1px solid #ddd; +} +.table-bordered>thead>tr>th, .table-bordered>thead>tr>td { + border-bottom-width: 2px; +} +.table-striped>tbody>tr:nth-child(odd)>td, .table-striped>tbody>tr:nth-child(odd)>th { + background-color: #f9f9f9; +} +.table-hover>tbody>tr:hover>td, .table-hover>tbody>tr:hover>th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], table th[class*="col-"] { + display: table-cell; + float: none; +} +.table>thead>tr>.active, .table>tbody>tr>.active, .table>tfoot>tr>.active, .table>thead>.active>td, .table>tbody>.active>td, .table>tfoot>.active>td, .table>thead>.active>th, .table>tbody>.active>th, .table>tfoot>.active>th { + background-color: #f5f5f5; +} +.table-hover>tbody>tr>.active:hover, .table-hover>tbody>.active:hover>td, .table-hover>tbody>.active:hover>th { + background-color: #e8e8e8; +} +.table>thead>tr>.success, .table>tbody>tr>.success, .table>tfoot>tr>.success, .table>thead>.success>td, .table>tbody>.success>td, .table>tfoot>.success>td, .table>thead>.success>th, .table>tbody>.success>th, .table>tfoot>.success>th { + background-color: #dff0d8; +} +.table-hover>tbody>tr>.success:hover, .table-hover>tbody>.success:hover>td, .table-hover>tbody>.success:hover>th { + background-color: #d0e9c6; +} +.table>thead>tr>.danger, .table>tbody>tr>.danger, .table>tfoot>tr>.danger, .table>thead>.danger>td, .table>tbody>.danger>td, .table>tfoot>.danger>td, .table>thead>.danger>th, .table>tbody>.danger>th, .table>tfoot>.danger>th { + background-color: #f2dede; +} +.table-hover>tbody>tr>.danger:hover, .table-hover>tbody>.danger:hover>td, .table-hover>tbody>.danger:hover>th { + background-color: #ebcccc; +} +.table>thead>tr>.warning, .table>tbody>tr>.warning, .table>tfoot>tr>.warning, .table>thead>.warning>td, .table>tbody>.warning>td, .table>tfoot>.warning>td, .table>thead>.warning>th, .table>tbody>.warning>th, .table>tfoot>.warning>th { + background-color: #fcf8e3; +} +.table-hover>tbody>tr>.warning:hover, .table-hover>tbody>.warning:hover>td, .table-hover>tbody>.warning:hover>th { + background-color: #faf2cc; +} +@media(max-width:767px) { + .table-responsive { + width: 100%; + margin-bottom: 15.75px; + overflow-x: scroll; + overflow-y: hidden; + border: 1px solid #ddd; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; +} +.table-responsive>.table { + margin-bottom: 0; +} +.table-responsive>.table>thead>tr>th, .table-responsive>.table>tbody>tr>th, .table-responsive>.table>tfoot>tr>th, .table-responsive>.table>thead>tr>td, .table-responsive>.table>tbody>tr>td, .table-responsive>.table>tfoot>tr>td { + white-space: nowrap; +} +.table-responsive>.table-bordered { + border: 0; +} +.table-responsive>.table-bordered>thead>tr>th:first-child, .table-responsive>.table-bordered>tbody>tr>th:first-child, .table-responsive>.table-bordered>tfoot>tr>th:first-child, .table-responsive>.table-bordered>thead>tr>td:first-child, .table-responsive>.table-bordered>tbody>tr>td:first-child, .table-responsive>.table-bordered>tfoot>tr>td:first-child { + border-left: 0; +} +.table-responsive>.table-bordered>thead>tr>th:last-child, .table-responsive>.table-bordered>tbody>tr>th:last-child, .table-responsive>.table-bordered>tfoot>tr>th:last-child, .table-responsive>.table-bordered>thead>tr>td:last-child, .table-responsive>.table-bordered>tbody>tr>td:last-child, .table-responsive>.table-bordered>tfoot>tr>td:last-child { + border-right: 0; +} +.table-responsive>.table-bordered>tbody>tr:last-child>th, .table-responsive>.table-bordered>tfoot>tr:last-child>th, .table-responsive>.table-bordered>tbody>tr:last-child>td, .table-responsive>.table-bordered>tfoot>tr:last-child>td { + border-bottom: 0; +} +}fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 21px; + font-size: 22.5px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +select[multiple], select[size] { + height: auto; +} +select optgroup { + font-family: inherit; + font-size: inherit; + font-style: inherit; +} +input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { + height: auto; +} +output { + display: block; + padding-top: 7px; + font-size: 15px; + line-height: 1.428571429; + color: #6f6f6f; + vertical-align: middle; +} +.form-control { + display: block; + width: 100%; + height: 35px; + padding: 6px 12px; + font-size: 15px; + line-height: 1.428571429; + color: #6f6f6f; + vertical-align: middle; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control:-moz-placeholder { + color: #999; +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; +} +textarea.form-control { + height: auto; +} +.form-group { + margin-bottom: 15px; +} +.radio, .checkbox { + display: block; + min-height: 21px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; + vertical-align: middle; +} +.radio label, .checkbox label { + display: inline; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.radio+.radio, .checkbox+.checkbox { + margin-top: -5px; +} +.radio-inline, .checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline+.radio-inline, .checkbox-inline+.checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], input[type="checkbox"][disabled], .radio[disabled], .radio-inline[disabled], .checkbox[disabled], .checkbox-inline[disabled], fieldset[disabled] input[type="radio"], fieldset[disabled] input[type="checkbox"], fieldset[disabled] .radio, fieldset[disabled] .radio-inline, fieldset[disabled] .checkbox, fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm { + height: auto; +} +.input-lg { + height: 48px; + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +select.input-lg { + height: 48px; + line-height: 48px; +} +textarea.input-lg { + height: auto; +} +.has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline { + color: #e99002; +} +.has-warning .form-control { + border-color: #e99002; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #b67102; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #febc53; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #febc53; +} +.has-warning .input-group-addon { + color: #e99002; + background-color: #fcf8e3; + border-color: #e99002; +} +.has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline { + color: #f04124; +} +.has-error .form-control { + border-color: #f04124; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #d32a0e; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f79483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f79483; +} +.has-error .input-group-addon { + color: #f04124; + background-color: #f2dede; + border-color: #f04124; +} +.has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline { + color: #43ac6a; +} +.has-success .form-control { + border-color: #43ac6a; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #358753; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #85d0a1; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #85d0a1; +} +.has-success .input-group-addon { + color: #43ac6a; + background-color: #dff0d8; + border-color: #43ac6a; +} +.form-control-static { + margin-bottom: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #626262; +} +@media(min-width:768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; +} +.form-inline .form-control { + display: inline-block; +} +.form-inline select.form-control { + width: auto; +} +.form-inline .radio, .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} +.form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; +} +}.form-horizontal .control-label, .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, .form-horizontal .checkbox { + min-height: 28px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-control-static { + padding-top: 7px; +} +@media(min-width:768px) { + .form-horizontal .control-label { + text-align: right; +} +}.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 15px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + border-radius: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.btn:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, .btn:focus { + color: #333; + text-decoration: none; +} +.btn:active, .btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, .btn[disabled], fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + opacity: .65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default { + color: #333; + background-color: #e7e7e7; + border-color: #dadada; +} +.btn-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { + color: #333; + background-color: #d3d3d3; + border-color: #bbb; +} +.btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, .btn-default.disabled:focus, .btn-default[disabled]:focus, fieldset[disabled] .btn-default:focus, .btn-default.disabled:active, .btn-default[disabled]:active, fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { + background-color: #e7e7e7; + border-color: #dadada; +} +.btn-default .badge { + color: #e7e7e7; + background-color: #fff; +} +.btn-primary { + color: #fff; + background-color: #008cba; + border-color: #0079a1; +} +.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { + color: #fff; + background-color: #006d91; + border-color: #004b63; +} +.btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { + background-color: #008cba; + border-color: #0079a1; +} +.btn-primary .badge { + color: #008cba; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #e99002; + border-color: #d08002; +} +.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { + color: #fff; + background-color: #c17702; + border-color: #935b01; +} +.btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, .btn-warning.disabled:focus, .btn-warning[disabled]:focus, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled:active, .btn-warning[disabled]:active, fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { + background-color: #e99002; + border-color: #d08002; +} +.btn-warning .badge { + color: #e99002; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #f04124; + border-color: #ea2f10; +} +.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { + color: #fff; + background-color: #dc2c0f; + border-color: #b1240c; +} +.btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, .btn-danger.disabled:focus, .btn-danger[disabled]:focus, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled:active, .btn-danger[disabled]:active, fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { + background-color: #f04124; + border-color: #ea2f10; +} +.btn-danger .badge { + color: #f04124; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #43ac6a; + border-color: #3c9a5f; +} +.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { + color: #fff; + background-color: #388f58; + border-color: #2b6e44; +} +.btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, .btn-success.disabled:focus, .btn-success[disabled]:focus, fieldset[disabled] .btn-success:focus, .btn-success.disabled:active, .btn-success[disabled]:active, fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { + background-color: #43ac6a; + border-color: #3c9a5f; +} +.btn-success .badge { + color: #43ac6a; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { + color: #fff; + background-color: #39b3d7; + border-color: #269abc; +} +.btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, .btn-info.disabled:focus, .btn-info[disabled]:focus, fieldset[disabled] .btn-info:focus, .btn-info.disabled:active, .btn-info[disabled]:active, fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #008cba; + cursor: pointer; + border-radius: 0; +} +.btn-link, .btn-link:active, .btn-link[disabled], fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { + border-color: transparent; +} +.btn-link:hover, .btn-link:focus { + color: #00526e; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { + color: #999; + text-decoration: none; +} +.btn-lg { + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +.btn-sm { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; +} +.btn-block+.btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { + width: 100%} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + transition: height .35s ease; +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon:empty { + width: 1em; +} +.glyphicon-asterisk:before { + content: "\2a"} +.glyphicon-plus:before { + content: "\2b"} +.glyphicon-euro:before { + content: "\20ac"} +.glyphicon-minus:before { + content: "\2212"} +.glyphicon-cloud:before { + content: "\2601"} +.glyphicon-envelope:before { + content: "\2709"} +.glyphicon-pencil:before { + content: "\270f"} +.glyphicon-glass:before { + content: "\e001"} +.glyphicon-music:before { + content: "\e002"} +.glyphicon-search:before { + content: "\e003"} +.glyphicon-heart:before { + content: "\e005"} +.glyphicon-star:before { + content: "\e006"} +.glyphicon-star-empty:before { + content: "\e007"} +.glyphicon-user:before { + content: "\e008"} +.glyphicon-film:before { + content: "\e009"} +.glyphicon-th-large:before { + content: "\e010"} +.glyphicon-th:before { + content: "\e011"} +.glyphicon-th-list:before { + content: "\e012"} +.glyphicon-ok:before { + content: "\e013"} +.glyphicon-remove:before { + content: "\e014"} +.glyphicon-zoom-in:before { + content: "\e015"} +.glyphicon-zoom-out:before { + content: "\e016"} +.glyphicon-off:before { + content: "\e017"} +.glyphicon-signal:before { + content: "\e018"} +.glyphicon-cog:before { + content: "\e019"} +.glyphicon-trash:before { + content: "\e020"} +.glyphicon-home:before { + content: "\e021"} +.glyphicon-file:before { + content: "\e022"} +.glyphicon-time:before { + content: "\e023"} +.glyphicon-road:before { + content: "\e024"} +.glyphicon-download-alt:before { + content: "\e025"} +.glyphicon-download:before { + content: "\e026"} +.glyphicon-upload:before { + content: "\e027"} +.glyphicon-inbox:before { + content: "\e028"} +.glyphicon-play-circle:before { + content: "\e029"} +.glyphicon-repeat:before { + content: "\e030"} +.glyphicon-refresh:before { + content: "\e031"} +.glyphicon-list-alt:before { + content: "\e032"} +.glyphicon-lock:before { + content: "\e033"} +.glyphicon-flag:before { + content: "\e034"} +.glyphicon-headphones:before { + content: "\e035"} +.glyphicon-volume-off:before { + content: "\e036"} +.glyphicon-volume-down:before { + content: "\e037"} +.glyphicon-volume-up:before { + content: "\e038"} +.glyphicon-qrcode:before { + content: "\e039"} +.glyphicon-barcode:before { + content: "\e040"} +.glyphicon-tag:before { + content: "\e041"} +.glyphicon-tags:before { + content: "\e042"} +.glyphicon-book:before { + content: "\e043"} +.glyphicon-bookmark:before { + content: "\e044"} +.glyphicon-print:before { + content: "\e045"} +.glyphicon-camera:before { + content: "\e046"} +.glyphicon-font:before { + content: "\e047"} +.glyphicon-bold:before { + content: "\e048"} +.glyphicon-italic:before { + content: "\e049"} +.glyphicon-text-height:before { + content: "\e050"} +.glyphicon-text-width:before { + content: "\e051"} +.glyphicon-align-left:before { + content: "\e052"} +.glyphicon-align-center:before { + content: "\e053"} +.glyphicon-align-right:before { + content: "\e054"} +.glyphicon-align-justify:before { + content: "\e055"} +.glyphicon-list:before { + content: "\e056"} +.glyphicon-indent-left:before { + content: "\e057"} +.glyphicon-indent-right:before { + content: "\e058"} +.glyphicon-facetime-video:before { + content: "\e059"} +.glyphicon-picture:before { + content: "\e060"} +.glyphicon-map-marker:before { + content: "\e062"} +.glyphicon-adjust:before { + content: "\e063"} +.glyphicon-tint:before { + content: "\e064"} +.glyphicon-edit:before { + content: "\e065"} +.glyphicon-share:before { + content: "\e066"} +.glyphicon-check:before { + content: "\e067"} +.glyphicon-move:before { + content: "\e068"} +.glyphicon-step-backward:before { + content: "\e069"} +.glyphicon-fast-backward:before { + content: "\e070"} +.glyphicon-backward:before { + content: "\e071"} +.glyphicon-play:before { + content: "\e072"} +.glyphicon-pause:before { + content: "\e073"} +.glyphicon-stop:before { + content: "\e074"} +.glyphicon-forward:before { + content: "\e075"} +.glyphicon-fast-forward:before { + content: "\e076"} +.glyphicon-step-forward:before { + content: "\e077"} +.glyphicon-eject:before { + content: "\e078"} +.glyphicon-chevron-left:before { + content: "\e079"} +.glyphicon-chevron-right:before { + content: "\e080"} +.glyphicon-plus-sign:before { + content: "\e081"} +.glyphicon-minus-sign:before { + content: "\e082"} +.glyphicon-remove-sign:before { + content: "\e083"} +.glyphicon-ok-sign:before { + content: "\e084"} +.glyphicon-question-sign:before { + content: "\e085"} +.glyphicon-info-sign:before { + content: "\e086"} +.glyphicon-screenshot:before { + content: "\e087"} +.glyphicon-remove-circle:before { + content: "\e088"} +.glyphicon-ok-circle:before { + content: "\e089"} +.glyphicon-ban-circle:before { + content: "\e090"} +.glyphicon-arrow-left:before { + content: "\e091"} +.glyphicon-arrow-right:before { + content: "\e092"} +.glyphicon-arrow-up:before { + content: "\e093"} +.glyphicon-arrow-down:before { + content: "\e094"} +.glyphicon-share-alt:before { + content: "\e095"} +.glyphicon-resize-full:before { + content: "\e096"} +.glyphicon-resize-small:before { + content: "\e097"} +.glyphicon-exclamation-sign:before { + content: "\e101"} +.glyphicon-gift:before { + content: "\e102"} +.glyphicon-leaf:before { + content: "\e103"} +.glyphicon-fire:before { + content: "\e104"} +.glyphicon-eye-open:before { + content: "\e105"} +.glyphicon-eye-close:before { + content: "\e106"} +.glyphicon-warning-sign:before { + content: "\e107"} +.glyphicon-plane:before { + content: "\e108"} +.glyphicon-calendar:before { + content: "\e109"} +.glyphicon-random:before { + content: "\e110"} +.glyphicon-comment:before { + content: "\e111"} +.glyphicon-magnet:before { + content: "\e112"} +.glyphicon-chevron-up:before { + content: "\e113"} +.glyphicon-chevron-down:before { + content: "\e114"} +.glyphicon-retweet:before { + content: "\e115"} +.glyphicon-shopping-cart:before { + content: "\e116"} +.glyphicon-folder-close:before { + content: "\e117"} +.glyphicon-folder-open:before { + content: "\e118"} +.glyphicon-resize-vertical:before { + content: "\e119"} +.glyphicon-resize-horizontal:before { + content: "\e120"} +.glyphicon-hdd:before { + content: "\e121"} +.glyphicon-bullhorn:before { + content: "\e122"} +.glyphicon-bell:before { + content: "\e123"} +.glyphicon-certificate:before { + content: "\e124"} +.glyphicon-thumbs-up:before { + content: "\e125"} +.glyphicon-thumbs-down:before { + content: "\e126"} +.glyphicon-hand-right:before { + content: "\e127"} +.glyphicon-hand-left:before { + content: "\e128"} +.glyphicon-hand-up:before { + content: "\e129"} +.glyphicon-hand-down:before { + content: "\e130"} +.glyphicon-circle-arrow-right:before { + content: "\e131"} +.glyphicon-circle-arrow-left:before { + content: "\e132"} +.glyphicon-circle-arrow-up:before { + content: "\e133"} +.glyphicon-circle-arrow-down:before { + content: "\e134"} +.glyphicon-globe:before { + content: "\e135"} +.glyphicon-wrench:before { + content: "\e136"} +.glyphicon-tasks:before { + content: "\e137"} +.glyphicon-filter:before { + content: "\e138"} +.glyphicon-briefcase:before { + content: "\e139"} +.glyphicon-fullscreen:before { + content: "\e140"} +.glyphicon-dashboard:before { + content: "\e141"} +.glyphicon-paperclip:before { + content: "\e142"} +.glyphicon-heart-empty:before { + content: "\e143"} +.glyphicon-link:before { + content: "\e144"} +.glyphicon-phone:before { + content: "\e145"} +.glyphicon-pushpin:before { + content: "\e146"} +.glyphicon-usd:before { + content: "\e148"} +.glyphicon-gbp:before { + content: "\e149"} +.glyphicon-sort:before { + content: "\e150"} +.glyphicon-sort-by-alphabet:before { + content: "\e151"} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"} +.glyphicon-sort-by-order:before { + content: "\e153"} +.glyphicon-sort-by-order-alt:before { + content: "\e154"} +.glyphicon-sort-by-attributes:before { + content: "\e155"} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"} +.glyphicon-unchecked:before { + content: "\e157"} +.glyphicon-expand:before { + content: "\e158"} +.glyphicon-collapse-down:before { + content: "\e159"} +.glyphicon-collapse-up:before { + content: "\e160"} +.glyphicon-log-in:before { + content: "\e161"} +.glyphicon-flash:before { + content: "\e162"} +.glyphicon-log-out:before { + content: "\e163"} +.glyphicon-new-window:before { + content: "\e164"} +.glyphicon-record:before { + content: "\e165"} +.glyphicon-save:before { + content: "\e166"} +.glyphicon-open:before { + content: "\e167"} +.glyphicon-saved:before { + content: "\e168"} +.glyphicon-import:before { + content: "\e169"} +.glyphicon-export:before { + content: "\e170"} +.glyphicon-send:before { + content: "\e171"} +.glyphicon-floppy-disk:before { + content: "\e172"} +.glyphicon-floppy-saved:before { + content: "\e173"} +.glyphicon-floppy-remove:before { + content: "\e174"} +.glyphicon-floppy-save:before { + content: "\e175"} +.glyphicon-floppy-open:before { + content: "\e176"} +.glyphicon-credit-card:before { + content: "\e177"} +.glyphicon-transfer:before { + content: "\e178"} +.glyphicon-cutlery:before { + content: "\e179"} +.glyphicon-header:before { + content: "\e180"} +.glyphicon-compressed:before { + content: "\e181"} +.glyphicon-earphone:before { + content: "\e182"} +.glyphicon-phone-alt:before { + content: "\e183"} +.glyphicon-tower:before { + content: "\e184"} +.glyphicon-stats:before { + content: "\e185"} +.glyphicon-sd-video:before { + content: "\e186"} +.glyphicon-hd-video:before { + content: "\e187"} +.glyphicon-subtitles:before { + content: "\e188"} +.glyphicon-sound-stereo:before { + content: "\e189"} +.glyphicon-sound-dolby:before { + content: "\e190"} +.glyphicon-sound-5-1:before { + content: "\e191"} +.glyphicon-sound-6-1:before { + content: "\e192"} +.glyphicon-sound-7-1:before { + content: "\e193"} +.glyphicon-copyright-mark:before { + content: "\e194"} +.glyphicon-registration-mark:before { + content: "\e195"} +.glyphicon-cloud-download:before { + content: "\e197"} +.glyphicon-cloud-upload:before { + content: "\e198"} +.glyphicon-tree-conifer:before { + content: "\e199"} +.glyphicon-tree-deciduous:before { + content: "\e200"} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 15px; + list-style: none; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9.5px 0; + overflow: hidden; + background-color: rgba(0, 0, 0, 0.2); +} +.dropdown-menu>li>a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #555; + white-space: nowrap; +} +.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus { + color: #262626; + text-decoration: none; + background-color: #eee; +} +.dropdown-menu>.active>a, .dropdown-menu>.active>a:hover, .dropdown-menu>.active>a:focus { + color: #fff; + text-decoration: none; + background-color: #008cba; + outline: 0; +} +.dropdown-menu>.disabled>a, .dropdown-menu>.disabled>a:hover, .dropdown-menu>.disabled>a:focus { + color: #999; +} +.dropdown-menu>.disabled>a:hover, .dropdown-menu>.disabled>a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} +.open>.dropdown-menu { + display: block; +} +.open>a { + outline: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right>.dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, .navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid; + content: ""} +.dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media(min-width:768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; +} +}.btn-group, .btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group>.btn, .btn-group-vertical>.btn { + position: relative; + float: left; +} +.btn-group>.btn:hover, .btn-group-vertical>.btn:hover, .btn-group>.btn:focus, .btn-group-vertical>.btn:focus, .btn-group>.btn:active, .btn-group-vertical>.btn:active, .btn-group>.btn.active, .btn-group-vertical>.btn.active { + z-index: 2; +} +.btn-group>.btn:focus, .btn-group-vertical>.btn:focus { + outline: 0; +} +.btn-group .btn+.btn, .btn-group .btn+.btn-group, .btn-group .btn-group+.btn, .btn-group .btn-group+.btn-group { + margin-left: -1px; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar .btn-group { + float: left; +} +.btn-toolbar>.btn+.btn, .btn-toolbar>.btn-group+.btn, .btn-toolbar>.btn+.btn-group, .btn-toolbar>.btn-group+.btn-group { + margin-left: 5px; +} +.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group>.btn:first-child { + margin-left: 0; +} +.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group>.btn:last-child:not(:first-child), .btn-group>.dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group>.btn-group { + float: left; +} +.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn { + border-radius: 0; +} +.btn-group>.btn-group:first-child>.btn:last-child, .btn-group>.btn-group:first-child>.dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group>.btn-group:last-child>.btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group-xs>.btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-group-sm>.btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-group-lg>.btn { + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +.btn-group>.btn+.dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group>.btn-lg+.dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical>.btn, .btn-group-vertical>.btn-group, .btn-group-vertical>.btn-group>.btn { + display: block; + float: none; + width: 100%; + max-width: 100%} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group>.btn { + float: none; +} +.btn-group-vertical>.btn+.btn, .btn-group-vertical>.btn+.btn-group, .btn-group-vertical>.btn-group+.btn, .btn-group-vertical>.btn-group+.btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical>.btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical>.btn:first-child:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical>.btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn { + border-radius: 0; +} +.btn-group-vertical>.btn-group:first-child>.btn:last-child, .btn-group-vertical>.btn-group:first-child>.dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical>.btn-group:last-child>.btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + border-collapse: separate; + table-layout: fixed; +} +.btn-group-justified>.btn, .btn-group-justified>.btn-group { + display: table-cell; + float: none; + width: 1%} +.btn-group-justified>.btn-group .btn { + width: 100%} +[data-toggle="buttons"]>.btn>input[type="radio"], [data-toggle="buttons"]>.btn>input[type="checkbox"] { + display: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + width: 100%; + margin-bottom: 0; +} +.input-group-lg>.form-control, .input-group-lg>.input-group-addon, .input-group-lg>.input-group-btn>.btn { + height: 48px; + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +select.input-group-lg>.form-control, select.input-group-lg>.input-group-addon, select.input-group-lg>.input-group-btn>.btn { + height: 48px; + line-height: 48px; +} +textarea.input-group-lg>.form-control, textarea.input-group-lg>.input-group-addon, textarea.input-group-lg>.input-group-btn>.btn { + height: auto; +} +.input-group-sm>.form-control, .input-group-sm>.input-group-addon, .input-group-sm>.input-group-btn>.btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +select.input-group-sm>.form-control, select.input-group-sm>.input-group-addon, select.input-group-sm>.input-group-btn>.btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm>.form-control, textarea.input-group-sm>.input-group-addon, textarea.input-group-sm>.input-group-btn>.btn { + height: auto; +} +.input-group-addon, .input-group-btn, .input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, .input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 15px; + font-weight: normal; + line-height: 1; + color: #6f6f6f; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 0; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 0; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 19px; + border-radius: 0; +} +.input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child>.btn, .input-group-btn:first-child>.dropdown-toggle, .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child>.btn, .input-group-btn:last-child>.dropdown-toggle, .input-group-btn:first-child>.btn:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + white-space: nowrap; +} +.input-group-btn:first-child>.btn { + margin-right: -1px; +} +.input-group-btn:last-child>.btn { + margin-left: -1px; +} +.input-group-btn>.btn { + position: relative; +} +.input-group-btn>.btn+.btn { + margin-left: -4px; +} +.input-group-btn>.btn:hover, .input-group-btn>.btn:active { + z-index: 2; +} +.nav { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav>li { + position: relative; + display: block; +} +.nav>li>a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav>li>a:hover, .nav>li>a:focus { + text-decoration: none; + background-color: #eee; +} +.nav>li.disabled>a { + color: #999; +} +.nav>li.disabled>a:hover, .nav>li.disabled>a:focus { + color: #999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open>a, .nav .open>a:hover, .nav .open>a:focus { + background-color: #eee; + border-color: #008cba; +} +.nav .nav-divider { + height: 1px; + margin: 9.5px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav>li>a>img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs>li { + float: left; + margin-bottom: -1px; +} +.nav-tabs>li>a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 0; +} +.nav-tabs>li>a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs>li.active>a, .nav-tabs>li.active>a:hover, .nav-tabs>li.active>a:focus { + color: #6f6f6f; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified>li { + float: none; +} +.nav-tabs.nav-justified>li>a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified>.dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media(min-width:768px) { + .nav-tabs.nav-justified>li { + display: table-cell; + width: 1%} +.nav-tabs.nav-justified>li>a { + margin-bottom: 0; +} +}.nav-tabs.nav-justified>li>a { + margin-right: 0; + border-radius: 0; +} +.nav-tabs.nav-justified>.active>a, .nav-tabs.nav-justified>.active>a:hover, .nav-tabs.nav-justified>.active>a:focus { + border: 1px solid #ddd; +} +@media(min-width:768px) { + .nav-tabs.nav-justified>li>a { + border-bottom: 1px solid #ddd; + border-radius: 0; +} +.nav-tabs.nav-justified>.active>a, .nav-tabs.nav-justified>.active>a:hover, .nav-tabs.nav-justified>.active>a:focus { + border-bottom-color: #fff; +} +}.nav-pills>li { + float: left; +} +.nav-pills>li>a { + border-radius: 0; +} +.nav-pills>li+li { + margin-left: 2px; +} +.nav-pills>li.active>a, .nav-pills>li.active>a:hover, .nav-pills>li.active>a:focus { + color: #fff; + background-color: #008cba; +} +.nav-stacked>li { + float: none; +} +.nav-stacked>li+li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%} +.nav-justified>li { + float: none; +} +.nav-justified>li>a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified>.dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media(min-width:768px) { + .nav-justified>li { + display: table-cell; + width: 1%} +.nav-justified>li>a { + margin-bottom: 0; +} +}.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified>li>a { + margin-right: 0; + border-radius: 0; +} +.nav-tabs-justified>.active>a, .nav-tabs-justified>.active>a:hover, .nav-tabs-justified>.active>a:focus { + border: 1px solid #ddd; +} +@media(min-width:768px) { + .nav-tabs-justified>li>a { + border-bottom: 1px solid #ddd; + border-radius: 0; +} +.nav-tabs-justified>.active>a, .nav-tabs-justified>.active>a:hover, .nav-tabs-justified>.active>a:focus { + border-bottom-color: #fff; +} +}.tab-content>.tab-pane { + display: none; +} +.tab-content>.active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 45px; + margin-bottom: 21px; + border: 1px solid transparent; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +@media(min-width:768px) { + .navbar { + border-radius: 0; +} +}.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +@media(min-width:768px) { + .navbar-header { + float: left; +} +}.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media(min-width:768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; +} +.navbar-collapse.collapse { + display: block!important; + height: auto!important; + padding-bottom: 0; + overflow: visible!important; +} +.navbar-collapse.in { + overflow-y: visible; +} +.navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; +} +}.container>.navbar-header, .container>.navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media(min-width:768px) { + .container>.navbar-header, .container>.navbar-collapse { + margin-right: 0; + margin-left: 0; +} +}.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media(min-width:768px) { + .navbar-static-top { + border-radius: 0; +} +}.navbar-fixed-top, .navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media(min-width:768px) { + .navbar-fixed-top, .navbar-fixed-bottom { + border-radius: 0; +} +}.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + float: left; + padding: 12px 15px; + font-size: 19px; + line-height: 21px; +} +.navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; +} +@media(min-width:768px) { + .navbar>.container .navbar-brand { + margin-left: -15px; +} +}.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 5.5px; + margin-right: 15px; + margin-bottom: 5.5px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar+.icon-bar { + margin-top: 4px; +} +@media(min-width:768px) { + .navbar-toggle { + display: none; +} +}.navbar-nav { + margin: 6px -15px; +} +.navbar-nav>li>a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 21px; +} +@media(max-width:767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; +} +.navbar-nav .open .dropdown-menu>li>a, .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; +} +.navbar-nav .open .dropdown-menu>li>a { + line-height: 21px; +} +.navbar-nav .open .dropdown-menu>li>a:hover, .navbar-nav .open .dropdown-menu>li>a:focus { + background-image: none; +} +}@media(min-width:768px) { + .navbar-nav { + float: left; + margin: 0; +} +.navbar-nav>li { + float: left; +} +.navbar-nav>li>a { + padding-top: 12px; + padding-bottom: 12px; +} +.navbar-nav.navbar-right:last-child { + margin-right: -15px; +} +}@media(min-width:768px) { + .navbar-left { + float: left!important; +} +.navbar-right { + float: right!important; +} +}.navbar-form { + padding: 10px 15px; + margin-top: 5px; + margin-right: -15px; + margin-bottom: 5px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); +} +@media(min-width:768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; +} +.navbar-form .form-control { + display: inline-block; +} +.navbar-form select.form-control { + width: auto; +} +.navbar-form .radio, .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} +.navbar-form .radio input[type="radio"], .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; +} +}@media(max-width:767px) { + .navbar-form .form-group { + margin-bottom: 5px; +} +}@media(min-width:768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar-form.navbar-right:last-child { + margin-right: -15px; +} +}.navbar-nav>li>.dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-nav.pull-right>li>.dropdown-menu, .navbar-nav>li>.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.navbar-btn { + margin-top: 5px; + margin-bottom: 5px; +} +.navbar-btn.btn-sm { + margin-top: 7.5px; + margin-bottom: 7.5px; +} +.navbar-btn.btn-xs { + margin-top: 11.5px; + margin-bottom: 11.5px; +} +.navbar-text { + margin-top: 12px; + margin-bottom: 12px; +} +@media(min-width:768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; +} +.navbar-text.navbar-right:last-child { + margin-right: 0; +} +}.navbar-default { + background-color: #333; + border-color: #222; +} +.navbar-default .navbar-brand { + color: #fff; +} +.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #fff; +} +.navbar-default .navbar-nav>li>a { + color: #fff; +} +.navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav>.active>a, .navbar-default .navbar-nav>.active>a:hover, .navbar-default .navbar-nav>.active>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav>.disabled>a, .navbar-default .navbar-nav>.disabled>a:hover, .navbar-default .navbar-nav>.disabled>a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: transparent; +} +.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-default .navbar-collapse, .navbar-default .navbar-form { + border-color: #222; +} +.navbar-default .navbar-nav>.open>a, .navbar-default .navbar-nav>.open>a:hover, .navbar-default .navbar-nav>.open>a:focus { + color: #fff; + background-color: #272727; +} +@media(max-width:767px) { + .navbar-default .navbar-nav .open .dropdown-menu>li>a { + color: #fff; +} +.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover, .navbar-default .navbar-nav .open .dropdown-menu>li>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav .open .dropdown-menu>.active>a, .navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover, .navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a, .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover, .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus { + color: #ccc; + background-color: transparent; +} +}.navbar-default .navbar-link { + color: #fff; +} +.navbar-default .navbar-link:hover { + color: #fff; +} +.navbar-inverse { + background-color: #008cba; + border-color: #006687; +} +.navbar-inverse .navbar-brand { + color: #fff; +} +.navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #fff; +} +.navbar-inverse .navbar-nav>li>a { + color: #fff; +} +.navbar-inverse .navbar-nav>li>a:hover, .navbar-inverse .navbar-nav>li>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav>.active>a, .navbar-inverse .navbar-nav>.active>a:hover, .navbar-inverse .navbar-nav>.active>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav>.disabled>a, .navbar-inverse .navbar-nav>.disabled>a:hover, .navbar-inverse .navbar-nav>.disabled>a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: transparent; +} +.navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { + background-color: transparent; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { + border-color: #007196; +} +.navbar-inverse .navbar-nav>.open>a, .navbar-inverse .navbar-nav>.open>a:hover, .navbar-inverse .navbar-nav>.open>a:focus { + color: #fff; + background-color: #006687; +} +@media(max-width:767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header { + border-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>li>a { + color: #fff; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a, .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a, .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus { + color: #444; + background-color: transparent; +} +}.navbar-inverse .navbar-link { + color: #fff; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 21px; + list-style: none; + background-color: #f5f5f5; + border-radius: 0; +} +.breadcrumb>li { + display: inline-block; +} +.breadcrumb>li+li:before { + padding: 0 5px; + color: #999; + content: "/\00a0"} +.breadcrumb>.active { + color: #333; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 21px 0; + border-radius: 0; +} +.pagination>li { + display: inline; +} +.pagination>li>a, .pagination>li>span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.428571429; + text-decoration: none; + background-color: transparent; + border: 1px solid transparent; +} +.pagination>li:first-child>a, .pagination>li:first-child>span { + margin-left: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination>li:last-child>a, .pagination>li:last-child>span { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.pagination>li>a:hover, .pagination>li>span:hover, .pagination>li>a:focus, .pagination>li>span:focus { + background-color: #eee; +} +.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #008cba; + border-color: #008cba; +} +.pagination>.disabled>span, .pagination>.disabled>span:hover, .pagination>.disabled>span:focus, .pagination>.disabled>a, .pagination>.disabled>a:hover, .pagination>.disabled>a:focus { + color: #999; + cursor: not-allowed; + background-color: transparent; + border-color: transparent; +} +.pagination-lg>li>a, .pagination-lg>li>span { + padding: 10px 16px; + font-size: 19px; +} +.pagination-lg>li:first-child>a, .pagination-lg>li:first-child>span { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination-lg>li:last-child>a, .pagination-lg>li:last-child>span { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.pagination-sm>li>a, .pagination-sm>li>span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm>li:first-child>a, .pagination-sm>li:first-child>span { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination-sm>li:last-child>a, .pagination-sm>li:last-child>span { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.pager { + padding-left: 0; + margin: 21px 0; + text-align: center; + list-style: none; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li>a, .pager li>span { + display: inline-block; + padding: 5px 14px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 3px; +} +.pager li>a:hover, .pager li>a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next>a, .pager .next>span { + float: right; +} +.pager .previous>a, .pager .previous>span { + float: left; +} +.pager .disabled>a, .pager .disabled>a:hover, .pager .disabled>a:focus, .pager .disabled>span { + color: #999; + cursor: not-allowed; + background-color: transparent; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +.label[href]:hover, .label[href]:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #999; +} +.label-default[href]:hover, .label-default[href]:focus { + background-color: #808080; +} +.label-primary { + background-color: #008cba; +} +.label-primary[href]:hover, .label-primary[href]:focus { + background-color: #006687; +} +.label-success { + background-color: #43ac6a; +} +.label-success[href]:hover, .label-success[href]:focus { + background-color: #358753; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, .label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #e99002; +} +.label-warning[href]:hover, .label-warning[href]:focus { + background-color: #b67102; +} +.label-danger { + background-color: #f04124; +} +.label-danger[href]:hover, .label-danger[href]:focus { + background-color: #d32a0e; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #777; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #e7e7e7; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +a.badge:hover, a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active>.badge, .nav-pills>.active>a>.badge { + color: #008cba; + background-color: #fff; +} +.nav-pills>li>a>.badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + font-size: 23px; + font-weight: 200; + line-height: 2.1428571435; + color: inherit; + background-color: #fafafa; +} +.jumbotron h1, .jumbotron .h1 { + line-height: 1; + color: inherit; +} +.jumbotron p { + line-height: 1.4; +} +.container .jumbotron { + border-radius: 0; +} +.jumbotron .container { + max-width: 100%} +@media screen and (min-width:768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; +} +.container .jumbotron { + padding-right: 60px; + padding-left: 60px; +} +.jumbotron h1, .jumbotron .h1 { + font-size: 67.5px; +} +}.thumbnail { + display: block; + padding: 4px; + margin-bottom: 21px; + line-height: 1.428571429; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.thumbnail>img, .thumbnail a>img { + display: block; + height: auto; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { + border-color: #008cba; +} +.thumbnail .caption { + padding: 9px; + color: #222; +} +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; + } + + .alert-heading { + color: inherit; + } + + .alert-link { + font-weight: 700; + } + + .alert-dismissible { + padding-right: 4rem; + } + + .alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; + } + + .alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; + } + + .alert-primary hr { + border-top-color: #9fcdff; + } + + .alert-primary .alert-link { + color: #002752; + } + + .alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; + } + + .alert-secondary hr { + border-top-color: #c8cbcf; + } + + .alert-secondary .alert-link { + color: #202326; + } + + .alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; + } + + .alert-success hr { + border-top-color: #b1dfbb; + } + + .alert-success .alert-link { + color: #0b2e13; + } + + .alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; + } + + .alert-info hr { + border-top-color: #abdde5; + } + + .alert-info .alert-link { + color: #062c33; + } + + .alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; + } + + .alert-warning hr { + border-top-color: #ffe8a1; + } + + .alert-warning .alert-link { + color: #533f03; + } + + .alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; + } + + .alert-danger hr { + border-top-color: #f1b0b7; + } + + .alert-danger .alert-link { + color: #491217; + } + + .alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; + } + + .alert-light hr { + border-top-color: #ececf6; + } + + .alert-light .alert-link { + color: #686868; + } + + .alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; + } + + .alert-dark hr { + border-top-color: #b9bbbe; + } + + .alert-dark .alert-link { + color: #040505; + } + + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; +} +to { + background-position: 0 0; +} +}@keyframes progress-bar-stripes { + from { + background-position: 40px 0; +} +to { + background-position: 0 0; +} +}.progress { + height: 21px; + margin-bottom: 21px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 21px; + color: #fff; + text-align: center; + background-color: #008cba; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #43ac6a; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #e99002; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #f04124; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media, .media-body { + overflow: hidden; + zoom: 1; +} +.media, .media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media>.pull-left { + margin-right: 10px; +} +.media>.pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.list-group-item>.badge { + float: right; +} +.list-group-item>.badge+.badge { + margin-right: 5px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} +a.list-group-item.active, a.list-group-item.active:hover, a.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #008cba; + border-color: #008cba; +} +a.list-group-item.active .list-group-item-heading, a.list-group-item.active:hover .list-group-item-heading, a.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} +a.list-group-item.active .list-group-item-text, a.list-group-item.active:hover .list-group-item-text, a.list-group-item.active:focus .list-group-item-text { + color: #87e1ff; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 21px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel>.list-group { + margin-bottom: 0; +} +.panel>.list-group .list-group-item { + border-width: 1px 0; +} +.panel>.list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel>.list-group .list-group-item:last-child { + border-bottom: 0; +} +.panel-heading+.list-group .list-group-item:first-child { + border-top-width: 0; +} +.panel>.table, .panel>.table-responsive>.table { + margin-bottom: 0; +} +.panel>.panel-body+.table, .panel>.panel-body+.table-responsive { + border-top: 1px solid #ddd; +} +.panel>.table>tbody:first-child th, .panel>.table>tbody:first-child td { + border-top: 0; +} +.panel>.table-bordered, .panel>.table-responsive>.table-bordered { + border: 0; +} +.panel>.table-bordered>thead>tr>th:first-child, .panel>.table-responsive>.table-bordered>thead>tr>th:first-child, .panel>.table-bordered>tbody>tr>th:first-child, .panel>.table-responsive>.table-bordered>tbody>tr>th:first-child, .panel>.table-bordered>tfoot>tr>th:first-child, .panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child, .panel>.table-bordered>thead>tr>td:first-child, .panel>.table-responsive>.table-bordered>thead>tr>td:first-child, .panel>.table-bordered>tbody>tr>td:first-child, .panel>.table-responsive>.table-bordered>tbody>tr>td:first-child, .panel>.table-bordered>tfoot>tr>td:first-child, .panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child { + border-left: 0; +} +.panel>.table-bordered>thead>tr>th:last-child, .panel>.table-responsive>.table-bordered>thead>tr>th:last-child, .panel>.table-bordered>tbody>tr>th:last-child, .panel>.table-responsive>.table-bordered>tbody>tr>th:last-child, .panel>.table-bordered>tfoot>tr>th:last-child, .panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child, .panel>.table-bordered>thead>tr>td:last-child, .panel>.table-responsive>.table-bordered>thead>tr>td:last-child, .panel>.table-bordered>tbody>tr>td:last-child, .panel>.table-responsive>.table-bordered>tbody>tr>td:last-child, .panel>.table-bordered>tfoot>tr>td:last-child, .panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child { + border-right: 0; +} +.panel>.table-bordered>thead>tr:last-child>th, .panel>.table-responsive>.table-bordered>thead>tr:last-child>th, .panel>.table-bordered>tbody>tr:last-child>th, .panel>.table-responsive>.table-bordered>tbody>tr:last-child>th, .panel>.table-bordered>tfoot>tr:last-child>th, .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th, .panel>.table-bordered>thead>tr:last-child>td, .panel>.table-responsive>.table-bordered>thead>tr:last-child>td, .panel>.table-bordered>tbody>tr:last-child>td, .panel>.table-responsive>.table-bordered>tbody>tr:last-child>td, .panel>.table-bordered>tfoot>tr:last-child>td, .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td { + border-bottom: 0; +} +.panel>.table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: -1; + border-top-left-radius: -1; +} +.panel-heading>.dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 17px; + color: inherit; +} +.panel-title>a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; +} +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 0; +} +.panel-group .panel+.panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading+.panel-collapse .panel-body { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer+.panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default>.panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default>.panel-heading+.panel-collapse .panel-body { + border-top-color: #ddd; +} +.panel-default>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #008cba; +} +.panel-primary>.panel-heading { + color: #fff; + background-color: #008cba; + border-color: #008cba; +} +.panel-primary>.panel-heading+.panel-collapse .panel-body { + border-top-color: #008cba; +} +.panel-primary>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #008cba; +} +.panel-success { + border-color: #3c9a5f; +} +.panel-success>.panel-heading { + color: #43ac6a; + background-color: #dff0d8; + border-color: #3c9a5f; +} +.panel-success>.panel-heading+.panel-collapse .panel-body { + border-top-color: #3c9a5f; +} +.panel-success>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #3c9a5f; +} +.panel-warning { + border-color: #d08002; +} +.panel-warning>.panel-heading { + color: #e99002; + background-color: #fcf8e3; + border-color: #d08002; +} +.panel-warning>.panel-heading+.panel-collapse .panel-body { + border-top-color: #d08002; +} +.panel-warning>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #d08002; +} +.panel-danger { + border-color: #ea2f10; +} +.panel-danger>.panel-heading { + color: #f04124; + background-color: #f2dede; + border-color: #ea2f10; +} +.panel-danger>.panel-heading+.panel-collapse .panel-body { + border-top-color: #ea2f10; +} +.panel-danger>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #ea2f10; +} +.panel-info { + border-color: #3db5d8; +} +.panel-info>.panel-heading { + color: #5bc0de; + background-color: #d9edf7; + border-color: #3db5d8; +} +.panel-info>.panel-heading+.panel-collapse .panel-body { + border-top-color: #3db5d8; +} +.panel-info>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #3db5d8; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #fafafa; + border: 1px solid #e8e8e8; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 0; +} +.well-sm { + padding: 9px; + border-radius: 0; +} +.close { + float: right; + font-size: 22.5px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .2; + filter: alpha(opacity=20); +} +.close:hover, .close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: .5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: auto; + overflow-y: scroll; +} +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform .3s ease-out; + -moz-transition: -moz-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-dialog { + position: relative; + z-index: 1050; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: .5; + filter: alpha(opacity=50); +} +.modal-header { + min-height: 16.428571429px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.428571429; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer .btn+.btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn+.btn { + margin-left: -1px; +} +.modal-footer .btn-block+.btn-block { + margin-left: 0; +} +@media screen and (min-width:768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; +} +.modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); +} +}.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} +.tooltip.in { + opacity: .9; + filter: alpha(opacity=90); +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #333; + border-radius: 0; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #333; + border-width: 5px 5px 0; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-top-color: #333; + border-width: 5px 5px 0; +} +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-top-color: #333; + border-width: 5px 5px 0; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #333; + border-width: 5px 5px 5px 0; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #333; + border-width: 5px 0 5px 5px; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #333; + border-width: 0 5px 5px; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-bottom-color: #333; + border-width: 0 5px 5px; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-bottom-color: #333; + border-width: 0 5px 5px; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #333; + border: 1px solid #333; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + background-clip: padding-box; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 15px; + font-weight: normal; + line-height: 18px; + background-color: #333; + border-bottom: 1px solid #262626; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, .popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""} +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #333; + border-bottom-width: 0; + content: " "} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #333; + border-left-width: 0; + content: " "} +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #333; + border-top-width: 0; + content: " "} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #333; + border-right-width: 0; + content: " "} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner>.item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner>.item>img, .carousel-inner>.item>a>img { + display: block; + height: auto; + max-width: 100%; + line-height: 1; +} +.carousel-inner>.active, .carousel-inner>.next, .carousel-inner>.prev { + display: block; +} +.carousel-inner>.active { + left: 0; +} +.carousel-inner>.next, .carousel-inner>.prev { + position: absolute; + top: 0; + width: 100%} +.carousel-inner>.next { + left: 100%} +.carousel-inner>.prev { + left: -100%} +.carousel-inner>.next.left, .carousel-inner>.prev.right { + left: 0; +} +.carousel-inner>.active.left { + left: -100%} +.carousel-inner>.active.right { + left: 100%} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + opacity: .5; + filter: alpha(opacity=50); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, .carousel-control:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { + left: 50%} +.carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { + right: 50%} +.carousel-control .icon-prev, .carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'} +.carousel-control .icon-next:before { + content: '\203a'} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width:768px) { + .carousel-control .glyphicons-chevron-left, .carousel-control .glyphicons-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; +} +.carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; +} +.carousel-indicators { + bottom: 20px; +} +}.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right!important; +} +.pull-left { + float: left!important; +} +.hide { + display: none!important; +} +.show { + display: block!important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none!important; + visibility: hidden!important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, tr.visible-xs, th.visible-xs, td.visible-xs { + display: none!important; +} +@media(max-width:767px) { + .visible-xs { + display: block!important; +} +table.visible-xs { + display: table; +} +tr.visible-xs { + display: table-row!important; +} +th.visible-xs, td.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-xs.visible-sm { + display: block!important; +} +table.visible-xs.visible-sm { + display: table; +} +tr.visible-xs.visible-sm { + display: table-row!important; +} +th.visible-xs.visible-sm, td.visible-xs.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-xs.visible-md { + display: block!important; +} +table.visible-xs.visible-md { + display: table; +} +tr.visible-xs.visible-md { + display: table-row!important; +} +th.visible-xs.visible-md, td.visible-xs.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-xs.visible-lg { + display: block!important; +} +table.visible-xs.visible-lg { + display: table; +} +tr.visible-xs.visible-lg { + display: table-row!important; +} +th.visible-xs.visible-lg, td.visible-xs.visible-lg { + display: table-cell!important; +} +}.visible-sm, tr.visible-sm, th.visible-sm, td.visible-sm { + display: none!important; +} +@media(max-width:767px) { + .visible-sm.visible-xs { + display: block!important; +} +table.visible-sm.visible-xs { + display: table; +} +tr.visible-sm.visible-xs { + display: table-row!important; +} +th.visible-sm.visible-xs, td.visible-sm.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-sm { + display: block!important; +} +table.visible-sm { + display: table; +} +tr.visible-sm { + display: table-row!important; +} +th.visible-sm, td.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-sm.visible-md { + display: block!important; +} +table.visible-sm.visible-md { + display: table; +} +tr.visible-sm.visible-md { + display: table-row!important; +} +th.visible-sm.visible-md, td.visible-sm.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-sm.visible-lg { + display: block!important; +} +table.visible-sm.visible-lg { + display: table; +} +tr.visible-sm.visible-lg { + display: table-row!important; +} +th.visible-sm.visible-lg, td.visible-sm.visible-lg { + display: table-cell!important; +} +}.visible-md, tr.visible-md, th.visible-md, td.visible-md { + display: none!important; +} +@media(max-width:767px) { + .visible-md.visible-xs { + display: block!important; +} +table.visible-md.visible-xs { + display: table; +} +tr.visible-md.visible-xs { + display: table-row!important; +} +th.visible-md.visible-xs, td.visible-md.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-md.visible-sm { + display: block!important; +} +table.visible-md.visible-sm { + display: table; +} +tr.visible-md.visible-sm { + display: table-row!important; +} +th.visible-md.visible-sm, td.visible-md.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-md { + display: block!important; +} +table.visible-md { + display: table; +} +tr.visible-md { + display: table-row!important; +} +th.visible-md, td.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-md.visible-lg { + display: block!important; +} +table.visible-md.visible-lg { + display: table; +} +tr.visible-md.visible-lg { + display: table-row!important; +} +th.visible-md.visible-lg, td.visible-md.visible-lg { + display: table-cell!important; +} +}.visible-lg, tr.visible-lg, th.visible-lg, td.visible-lg { + display: none!important; +} +@media(max-width:767px) { + .visible-lg.visible-xs { + display: block!important; +} +table.visible-lg.visible-xs { + display: table; +} +tr.visible-lg.visible-xs { + display: table-row!important; +} +th.visible-lg.visible-xs, td.visible-lg.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-lg.visible-sm { + display: block!important; +} +table.visible-lg.visible-sm { + display: table; +} +tr.visible-lg.visible-sm { + display: table-row!important; +} +th.visible-lg.visible-sm, td.visible-lg.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-lg.visible-md { + display: block!important; +} +table.visible-lg.visible-md { + display: table; +} +tr.visible-lg.visible-md { + display: table-row!important; +} +th.visible-lg.visible-md, td.visible-lg.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-lg { + display: block!important; +} +table.visible-lg { + display: table; +} +tr.visible-lg { + display: table-row!important; +} +th.visible-lg, td.visible-lg { + display: table-cell!important; +} +}.hidden-xs { + display: block!important; +} +table.hidden-xs { + display: table; +} +tr.hidden-xs { + display: table-row!important; +} +th.hidden-xs, td.hidden-xs { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-xs, tr.hidden-xs, th.hidden-xs, td.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-xs.hidden-sm, tr.hidden-xs.hidden-sm, th.hidden-xs.hidden-sm, td.hidden-xs.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-xs.hidden-md, tr.hidden-xs.hidden-md, th.hidden-xs.hidden-md, td.hidden-xs.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-xs.hidden-lg, tr.hidden-xs.hidden-lg, th.hidden-xs.hidden-lg, td.hidden-xs.hidden-lg { + display: none!important; +} +}.hidden-sm { + display: block!important; +} +table.hidden-sm { + display: table; +} +tr.hidden-sm { + display: table-row!important; +} +th.hidden-sm, td.hidden-sm { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-sm.hidden-xs, tr.hidden-sm.hidden-xs, th.hidden-sm.hidden-xs, td.hidden-sm.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-sm, tr.hidden-sm, th.hidden-sm, td.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-sm.hidden-md, tr.hidden-sm.hidden-md, th.hidden-sm.hidden-md, td.hidden-sm.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-sm.hidden-lg, tr.hidden-sm.hidden-lg, th.hidden-sm.hidden-lg, td.hidden-sm.hidden-lg { + display: none!important; +} +}.hidden-md { + display: block!important; +} +table.hidden-md { + display: table; +} +tr.hidden-md { + display: table-row!important; +} +th.hidden-md, td.hidden-md { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-md.hidden-xs, tr.hidden-md.hidden-xs, th.hidden-md.hidden-xs, td.hidden-md.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-md.hidden-sm, tr.hidden-md.hidden-sm, th.hidden-md.hidden-sm, td.hidden-md.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-md, tr.hidden-md, th.hidden-md, td.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-md.hidden-lg, tr.hidden-md.hidden-lg, th.hidden-md.hidden-lg, td.hidden-md.hidden-lg { + display: none!important; +} +}.hidden-lg { + display: block!important; +} +table.hidden-lg { + display: table; +} +tr.hidden-lg { + display: table-row!important; +} +th.hidden-lg, td.hidden-lg { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-lg.hidden-xs, tr.hidden-lg.hidden-xs, th.hidden-lg.hidden-xs, td.hidden-lg.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-lg.hidden-sm, tr.hidden-lg.hidden-sm, th.hidden-lg.hidden-sm, td.hidden-lg.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-lg.hidden-md, tr.hidden-lg.hidden-md, th.hidden-lg.hidden-md, td.hidden-lg.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-lg, tr.hidden-lg, th.hidden-lg, td.hidden-lg { + display: none!important; +} +}.visible-print, tr.visible-print, th.visible-print, td.visible-print { + display: none!important; +} +@media print { + .visible-print { + display: block!important; +} +table.visible-print { + display: table; +} +tr.visible-print { + display: table-row!important; +} +th.visible-print, td.visible-print { + display: table-cell!important; +} +.hidden-print, tr.hidden-print, th.hidden-print, td.hidden-print { + display: none!important; +} +}.navbar { + font-size: 13px; + font-weight: 300; + border: 0; +} +.navbar .navbar-toggle:hover .icon-bar { + background-color: #b3b3b3; +} +.navbar-collapse { + border-top-color: rgba(0, 0, 0, 0.2); + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar .dropdown-menu { + border: 0; +} +.navbar .dropdown-menu>li>a, .navbar .dropdown-menu>li>a:focus { + font-size: 13px; + font-weight: 300; + background-color: transparent; +} +.navbar .dropdown-header { + color: rgba(255, 255, 255, 0.5); +} +.navbar-default .dropdown-menu { + background-color: #333; +} +.navbar-default .dropdown-menu>li>a, .navbar-default .dropdown-menu>li>a:focus { + color: #fff; +} +.navbar-default .dropdown-menu>li>a:hover, .navbar-default .dropdown-menu>.active>a, .navbar-default .dropdown-menu>.active>a:hover { + background-color: #272727; +} +.navbar-inverse .dropdown-menu { + background-color: #008cba; +} +.navbar-inverse .dropdown-menu>li>a, .navbar-inverse .dropdown-menu>li>a:focus { + color: #fff; +} +.navbar-inverse .dropdown-menu>li>a:hover, .navbar-inverse .dropdown-menu>.active>a, .navbar-inverse .dropdown-menu>.active>a:hover { + background-color: #006687; +} +.btn { + padding: 14px 28px; +} +.btn-lg { + padding: 16px 32px; +} +.btn-sm { + padding: 8px 16px; +} +.btn-xs { + padding: 4px 8px; +} +.btn-group .btn~.dropdown-toggle { + padding-right: 16px; + padding-left: 16px; +} +.btn-group .dropdown-menu { + border-top-width: 0; +} +.btn-group.dropup .dropdown-menu { + margin-bottom: 0; + border-top-width: 1px; + border-bottom-width: 0; +} +.btn-group .dropdown-toggle.btn-default~.dropdown-menu { + background-color: #e7e7e7; + border-color: #dadada; +} +.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a { + color: #333; +} +.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover { + background-color: #d3d3d3; +} +.btn-group .dropdown-toggle.btn-primary~.dropdown-menu { + background-color: #008cba; + border-color: #0079a1; +} +.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover { + background-color: #006d91; +} +.btn-group .dropdown-toggle.btn-success~.dropdown-menu { + background-color: #43ac6a; + border-color: #3c9a5f; +} +.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover { + background-color: #388f58; +} +.btn-group .dropdown-toggle.btn-info~.dropdown-menu { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover { + background-color: #39b3d7; +} +.btn-group .dropdown-toggle.btn-warning~.dropdown-menu { + background-color: #e99002; + border-color: #d08002; +} +.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover { + background-color: #c17702; +} +.btn-group .dropdown-toggle.btn-danger~.dropdown-menu { + background-color: #f04124; + border-color: #ea2f10; +} +.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover { + background-color: #dc2c0f; +} +.lead { + color: #6f6f6f; +} +cite { + font-style: italic; +} +blockquote { + color: #6f6f6f; + border-left-width: 1px; +} +blockquote.pull-right { + border-right-width: 1px; +} +blockquote small { + font-size: 12px; + font-weight: 300; +} +table { + font-size: 12px; +} +input, .form-control { + padding: 7px; + font-size: 12px; +} +label, .control-label, .help-block, .checkbox, .radio { + font-size: 12px; + font-weight: normal; +} +.form-group .btn, .input-group-addon, .input-group-btn .btn { + padding: 8px 14px; + font-size: 12px; +} +.nav .open>a, .nav .open>a:hover, .nav .open>a:focus { + border-color: transparent; +} +.nav-tabs>li>a { + color: #222; + background-color: #e7e7e7; +} +.nav-tabs .caret { + border-top-color: #222; + border-bottom-color: #222; +} +.nav-pills { + font-weight: 300; +} +.breadcrumb { + font-size: 10px; + font-weight: 300; + text-transform: uppercase; + border: 1px solid #ddd; + border-radius: 3px; +} +.pagination { + font-size: 12px; + font-weight: 300; + color: #999; +} +.pagination>li>a, .pagination>li>span { + margin-left: 4px; + color: #999; +} +.pagination>.active>a, .pagination>.active>span { + color: #fff; +} +.pagination>li>a, .pagination>li:first-child>a, .pagination>li:last-child>a, .pagination>li>span, .pagination>li:first-child>span, .pagination>li:last-child>span { + border-radius: 3px; +} +.pagination-lg>li>a { + padding-right: 22px; + padding-left: 22px; +} +.pagination-sm>li>a { + padding: 0 5px; +} +.pager { + font-size: 12px; + font-weight: 300; + color: #999; +} +.list-group { + font-size: 12px; + font-weight: 300; +} +.label { + padding-right: 1em; + padding-left: 1em; + font-weight: 300; + border-radius: 0; +} +.label-default { + color: #333; + background-color: #e7e7e7; +} +.badge { + font-weight: 300; +} +.progress { + height: 22px; + padding: 2px; + background-color: #f6f6f6; + border: 1px solid #ccc; + -webkit-box-shadow: none; + box-shadow: none; +} +.dropdown-menu { + padding: 0; + margin-top: 0; + font-size: 12px; +} +.dropdown-menu>li>a { + padding: 12px 15px; +} +.dropdown-header { + padding-right: 15px; + padding-left: 15px; + font-size: 9px; + text-transform: uppercase; +} +.popover { + font-size: 12px; + font-weight: 300; + color: #fff; +} +.panel-heading, .panel-footer { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right!important; +} +.pull-left { + float: left!important; +} +.hide { + display: none!important; +} +.show { + display: block!important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none!important; + visibility: hidden!important; +} +.affix { + position: fixed; +} diff --git a/css/bootstrap-custom.min.css b/css/bootstrap-custom.min.css new file mode 100644 index 00000000..25d43d46 --- /dev/null +++ b/css/bootstrap-custom.min.css @@ -0,0 +1 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:Hack,monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000 !important;text-shadow:none !important;background:transparent !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.table td,.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:Merriweather,Georgia,serif;font-size:14px;line-height:1.428571429;color:#222;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#008cba;text-decoration:none}a:hover,a:focus{color:#00526e;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:0}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #ddd}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:21px;margin-bottom:10.5px}h1 small,h2 small,h3 small,h1 .small,h2 .small,h3 .small{font-size:65%}h4,h5,h6{margin-top:10.5px;margin-bottom:10.5px}h4 small,h5 small,h6 small,h4 .small,h5 .small,h6 .small{font-size:75%}h1,.h1{font-size:39px}h2,.h2{font-size:32px}h3,.h3{font-size:26px}h4,.h4{font-size:19px}h5,.h5{font-size:15px}h6,.h6{font-size:13px}p{margin:0 0 10.5px}.lead{margin-bottom:21px;font-size:17px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:22.5px}}small,.small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#008cba}.text-primary:hover{color:#006687}.text-warning{color:#e99002}.text-warning:hover{color:#b67102}.text-danger{color:#f04124}.text-danger:hover{color:#d32a0e}.text-success{color:#43ac6a}.text-success:hover{color:#358753}.text-info{color:#5bc0de}.text-info:hover{color:#31b0d5}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.page-header{padding-bottom:9.5px;margin:42px 0 21px;border-bottom:1px solid #ddd}ul,ol{margin-top:0;margin-bottom:10.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.list-inline>li:first-child{padding-left:0}dl{margin-top:0;margin-bottom:21px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10.5px 21px;margin:0 0 21px;border-left:5px solid #ddd}blockquote p{font-size:18.75px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small,blockquote .small{display:block;line-height:1.428571429;color:#6f6f6f}blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #ddd;border-left:0}blockquote.pull-right p,blockquote.pull-right small,blockquote.pull-right .small{text-align:right}blockquote.pull-right small:before,blockquote.pull-right .small:before{content:''}blockquote.pull-right small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:21px;font-style:normal;line-height:1.428571429}code,kbd,pre,samp{font-family:Hack,Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:0}pre{display:block;padding:10px;margin:0 0 10.5px;font-size:14px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:0}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}@media(min-width:768px){.container{width:750px}}@media(min-width:992px){.container{width:970px}}@media(min-width:1200px){.container{width:1170px}}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.col-xs-offset-0{margin-left:0}@media(min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media(min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media(min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:21px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{position:static;display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>.active,.table>tbody>tr>.active,.table>tfoot>tr>.active,.table>thead>.active>td,.table>tbody>.active>td,.table>tfoot>.active>td,.table>thead>.active>th,.table>tbody>.active>th,.table>tfoot>.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>.active:hover,.table-hover>tbody>.active:hover>td,.table-hover>tbody>.active:hover>th{background-color:#e8e8e8}.table>thead>tr>.success,.table>tbody>tr>.success,.table>tfoot>tr>.success,.table>thead>.success>td,.table>tbody>.success>td,.table>tfoot>.success>td,.table>thead>.success>th,.table>tbody>.success>th,.table>tfoot>.success>th{background-color:#dff0d8}.table-hover>tbody>tr>.success:hover,.table-hover>tbody>.success:hover>td,.table-hover>tbody>.success:hover>th{background-color:#d0e9c6}.table>thead>tr>.danger,.table>tbody>tr>.danger,.table>tfoot>tr>.danger,.table>thead>.danger>td,.table>tbody>.danger>td,.table>tfoot>.danger>td,.table>thead>.danger>th,.table>tbody>.danger>th,.table>tfoot>.danger>th{background-color:#f2dede}.table-hover>tbody>tr>.danger:hover,.table-hover>tbody>.danger:hover>td,.table-hover>tbody>.danger:hover>th{background-color:#ebcccc}.table>thead>tr>.warning,.table>tbody>tr>.warning,.table>tfoot>tr>.warning,.table>thead>.warning>td,.table>tbody>.warning>td,.table>tfoot>.warning>td,.table>thead>.warning>th,.table>tbody>.warning>th,.table>tfoot>.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>.warning:hover,.table-hover>tbody>.warning:hover>td,.table-hover>tbody>.warning:hover>th{background-color:#faf2cc}@media(max-width:767px){.table-responsive{width:100%;margin-bottom:15.75px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:21px;font-size:22.5px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}output{display:block;padding-top:7px;font-size:15px;line-height:1.428571429;color:#6f6f6f;vertical-align:middle}.form-control{display:block;width:100%;height:35px;padding:6px 12px;font-size:15px;line-height:1.428571429;color:#6f6f6f;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:21px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:48px;padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}select.input-lg{height:48px;line-height:48px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#e99002}.has-warning .form-control{border-color:#e99002;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#b67102;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53}.has-warning .input-group-addon{color:#e99002;background-color:#fcf8e3;border-color:#e99002}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#f04124}.has-error .form-control{border-color:#f04124;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#d32a0e;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483}.has-error .input-group-addon{color:#f04124;background-color:#f2dede;border-color:#f04124}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#43ac6a}.has-success .form-control{border-color:#43ac6a;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#358753;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1}.has-success .input-group-addon{color:#43ac6a;background-color:#dff0d8;border-color:#43ac6a}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#626262}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:28px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-control-static{padding-top:7px}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:15px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#e7e7e7;border-color:#dadada}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#d3d3d3;border-color:#bbb}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#e7e7e7;border-color:#dadada}.btn-default .badge{color:#e7e7e7;background-color:#fff}.btn-primary{color:#fff;background-color:#008cba;border-color:#0079a1}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#006d91;border-color:#004b63}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#008cba;border-color:#0079a1}.btn-primary .badge{color:#008cba;background-color:#fff}.btn-warning{color:#fff;background-color:#e99002;border-color:#d08002}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#c17702;border-color:#935b01}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#e99002;border-color:#d08002}.btn-warning .badge{color:#e99002;background-color:#fff}.btn-danger{color:#fff;background-color:#f04124;border-color:#ea2f10}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#dc2c0f;border-color:#b1240c}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#f04124;border-color:#ea2f10}.btn-danger .badge{color:#f04124;background-color:#fff}.btn-success{color:#fff;background-color:#43ac6a;border-color:#3c9a5f}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#388f58;border-color:#2b6e44}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#43ac6a;border-color:#3c9a5f}.btn-success .badge{color:#43ac6a;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-link{font-weight:normal;color:#008cba;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#00526e;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:0}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1;-moz-osx-font-smoothing:grayscale}.glyphicon:empty{width:1em}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:15px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,0.2)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#555;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#eee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#008cba;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:0}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}.btn-group-lg>.btn{padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:48px;padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:48px;line-height:48px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:15px;font-weight:normal;line-height:1;color:#6f6f6f;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:0}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:0}.input-group-addon.input-lg{padding:10px 16px;font-size:19px;border-radius:0}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn:first-child>.btn{margin-right:-1px}.input-group-btn:last-child>.btn{margin-left:-1px}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#008cba}.nav .nav-divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#6f6f6f;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:0}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#008cba}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:45px;margin-bottom:21px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:0}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;float:left;padding:12px 15px;font-size:19px;line-height:21px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:5.5px;margin-right:15px;margin-bottom:5.5px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:6px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:21px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:21px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:12px;padding-bottom:12px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media(min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important}}.navbar-form{padding:10px 15px;margin-top:5px;margin-right:-15px;margin-bottom:5px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:5px;margin-bottom:5px}.navbar-btn.btn-sm{margin-top:7.5px;margin-bottom:7.5px}.navbar-btn.btn-xs{margin-top:11.5px;margin-bottom:11.5px}.navbar-text{margin-top:12px;margin-bottom:12px}@media(min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#333;border-color:#222}.navbar-default .navbar-brand{color:#fff}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-default .navbar-text{color:#fff}.navbar-default .navbar-nav>li>a{color:#fff}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:#fff}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#222}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#fff;background-color:#272727}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#fff}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#fff}.navbar-default .navbar-link:hover{color:#fff}.navbar-inverse{background-color:#008cba;border-color:#006687}.navbar-inverse .navbar-brand{color:#fff}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#fff}.navbar-inverse .navbar-nav>li>a{color:#fff}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#007196}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#006687}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#fff}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:21px;list-style:none;background-color:#f5f5f5;border-radius:0}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#999;content:"/\00a0"}.breadcrumb>.active{color:#333}.pagination{display:inline-block;padding-left:0;margin:21px 0;border-radius:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:transparent;border:1px solid transparent}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#008cba;border-color:#008cba}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:transparent;border-color:transparent}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:19px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pager{padding-left:0;margin:21px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:transparent;border:1px solid transparent;border-radius:3px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:transparent}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#008cba}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#006687}.label-success{background-color:#43ac6a}.label-success[href]:hover,.label-success[href]:focus{background-color:#358753}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#e99002}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#b67102}.label-danger{background-color:#f04124}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#d32a0e}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#777;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#e7e7e7;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#008cba;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:23px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#fafafa}.jumbotron h1,.jumbotron .h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:0}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:67.5px}}.thumbnail{display:block;padding:4px;margin-bottom:21px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#008cba}.thumbnail .caption{padding:9px;color:#222}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:21px;margin-bottom:21px;overflow:hidden;background-color:#f5f5f5;border-radius:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:21px;color:#fff;text-align:center;background-color:#008cba;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#43ac6a}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#e99002}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#f04124}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#008cba;border-color:#008cba}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#87e1ff}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:21px;background-color:#fff;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child th,.panel>.table>tbody:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:last-child>th,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:last-child>td,.panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:-1;border-top-left-radius:-1}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:17px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#008cba}.panel-primary>.panel-heading{color:#fff;background-color:#008cba;border-color:#008cba}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#008cba}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#008cba}.panel-success{border-color:#3c9a5f}.panel-success>.panel-heading{color:#43ac6a;background-color:#dff0d8;border-color:#3c9a5f}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#3c9a5f}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#3c9a5f}.panel-warning{border-color:#d08002}.panel-warning>.panel-heading{color:#e99002;background-color:#fcf8e3;border-color:#d08002}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#d08002}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d08002}.panel-danger{border-color:#ea2f10}.panel-danger>.panel-heading{color:#f04124;background-color:#f2dede;border-color:#ea2f10}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ea2f10}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ea2f10}.panel-info{border-color:#3db5d8}.panel-info>.panel-heading{color:#5bc0de;background-color:#d9edf7;border-color:#3db5d8}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#3db5d8}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#3db5d8}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#fafafa;border:1px solid #e8e8e8;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:0}.well-sm{padding:9px;border-radius:0}.close{float:right;font-size:22.5px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:0;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#333;border-radius:0}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#333;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#333;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#333;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#333;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#333;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#333;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#333;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#333;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#333;border:1px solid #333;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:15px;font-weight:normal;line-height:18px;background-color:#333;border-bottom:1px solid #262626;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#333;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#333;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#333;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#333;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,tr.visible-xs,th.visible-xs,td.visible-xs{display:none !important}@media(max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block !important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row !important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block !important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row !important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block !important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row !important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell !important}}.visible-sm,tr.visible-sm,th.visible-sm,td.visible-sm{display:none !important}@media(max-width:767px){.visible-sm.visible-xs{display:block !important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row !important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block !important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row !important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block !important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row !important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell !important}}.visible-md,tr.visible-md,th.visible-md,td.visible-md{display:none !important}@media(max-width:767px){.visible-md.visible-xs{display:block !important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row !important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block !important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row !important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-md.visible-lg{display:block !important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row !important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell !important}}.visible-lg,tr.visible-lg,th.visible-lg,td.visible-lg{display:none !important}@media(max-width:767px){.visible-lg.visible-xs{display:block !important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row !important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block !important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row !important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block !important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row !important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}.hidden-xs{display:block !important}table.hidden-xs{display:table}tr.hidden-xs{display:table-row !important}th.hidden-xs,td.hidden-xs{display:table-cell !important}@media(max-width:767px){.hidden-xs,tr.hidden-xs,th.hidden-xs,td.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,tr.hidden-xs.hidden-md,th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none !important}}.hidden-sm{display:block !important}table.hidden-sm{display:table}tr.hidden-sm{display:table-row !important}th.hidden-sm,td.hidden-sm{display:table-cell !important}@media(max-width:767px){.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-sm,tr.hidden-sm,th.hidden-sm,td.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,tr.hidden-sm.hidden-md,th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none !important}}.hidden-md{display:block !important}table.hidden-md{display:table}tr.hidden-md{display:table-row !important}th.hidden-md,td.hidden-md{display:table-cell !important}@media(max-width:767px){.hidden-md.hidden-xs,tr.hidden-md.hidden-xs,th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,tr.hidden-md.hidden-sm,th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-md,tr.hidden-md,th.hidden-md,td.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-md.hidden-lg,tr.hidden-md.hidden-lg,th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none !important}}.hidden-lg{display:block !important}table.hidden-lg{display:table}tr.hidden-lg{display:table-row !important}th.hidden-lg,td.hidden-lg{display:table-cell !important}@media(max-width:767px){.hidden-lg.hidden-xs,tr.hidden-lg.hidden-xs,th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm,tr.hidden-lg.hidden-sm,th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md,tr.hidden-lg.hidden-md,th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-lg,tr.hidden-lg,th.hidden-lg,td.hidden-lg{display:none !important}}.visible-print,tr.visible-print,th.visible-print,td.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}.hidden-print,tr.hidden-print,th.hidden-print,td.hidden-print{display:none !important}}.navbar{font-size:13px;font-weight:300;border:0}.navbar .navbar-toggle:hover .icon-bar{background-color:#b3b3b3}.navbar-collapse{border-top-color:rgba(0,0,0,0.2);-webkit-box-shadow:none;box-shadow:none}.navbar .dropdown-menu{border:0}.navbar .dropdown-menu>li>a,.navbar .dropdown-menu>li>a:focus{font-size:13px;font-weight:300;background-color:transparent}.navbar .dropdown-header{color:rgba(255,255,255,0.5)}.navbar-default .dropdown-menu{background-color:#333}.navbar-default .dropdown-menu>li>a,.navbar-default .dropdown-menu>li>a:focus{color:#fff}.navbar-default .dropdown-menu>li>a:hover,.navbar-default .dropdown-menu>.active>a,.navbar-default .dropdown-menu>.active>a:hover{background-color:#272727}.navbar-inverse .dropdown-menu{background-color:#008cba}.navbar-inverse .dropdown-menu>li>a,.navbar-inverse .dropdown-menu>li>a:focus{color:#fff}.navbar-inverse .dropdown-menu>li>a:hover,.navbar-inverse .dropdown-menu>.active>a,.navbar-inverse .dropdown-menu>.active>a:hover{background-color:#006687}.btn{padding:14px 28px}.btn-lg{padding:16px 32px}.btn-sm{padding:8px 16px}.btn-xs{padding:4px 8px}.btn-group .btn~.dropdown-toggle{padding-right:16px;padding-left:16px}.btn-group .dropdown-menu{border-top-width:0}.btn-group.dropup .dropdown-menu{margin-bottom:0;border-top-width:1px;border-bottom-width:0}.btn-group .dropdown-toggle.btn-default~.dropdown-menu{background-color:#e7e7e7;border-color:#dadada}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a{color:#333}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover{background-color:#d3d3d3}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu{background-color:#008cba;border-color:#0079a1}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover{background-color:#006d91}.btn-group .dropdown-toggle.btn-success~.dropdown-menu{background-color:#43ac6a;border-color:#3c9a5f}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover{background-color:#388f58}.btn-group .dropdown-toggle.btn-info~.dropdown-menu{background-color:#5bc0de;border-color:#46b8da}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover{background-color:#39b3d7}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu{background-color:#e99002;border-color:#d08002}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover{background-color:#c17702}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu{background-color:#f04124;border-color:#ea2f10}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover{background-color:#dc2c0f}.lead{color:#6f6f6f}cite{font-style:italic}blockquote{color:#6f6f6f;border-left-width:1px}blockquote.pull-right{border-right-width:1px}blockquote small{font-size:12px;font-weight:300}table{font-size:12px}input,.form-control{padding:7px;font-size:12px}label,.control-label,.help-block,.checkbox,.radio{font-size:12px;font-weight:normal}.form-group .btn,.input-group-addon,.input-group-btn .btn{padding:8px 14px;font-size:12px}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:transparent}.nav-tabs>li>a{color:#222;background-color:#e7e7e7}.nav-tabs .caret{border-top-color:#222;border-bottom-color:#222}.nav-pills{font-weight:300}.breadcrumb{font-size:10px;font-weight:300;text-transform:uppercase;border:1px solid #ddd;border-radius:3px}.pagination{font-size:12px;font-weight:300;color:#999}.pagination>li>a,.pagination>li>span{margin-left:4px;color:#999}.pagination>.active>a,.pagination>.active>span{color:#fff}.pagination>li>a,.pagination>li:first-child>a,.pagination>li:last-child>a,.pagination>li>span,.pagination>li:first-child>span,.pagination>li:last-child>span{border-radius:3px}.pagination-lg>li>a{padding-right:22px;padding-left:22px}.pagination-sm>li>a{padding:0 5px}.pager{font-size:12px;font-weight:300;color:#999}.list-group{font-size:12px;font-weight:300}.label{padding-right:1em;padding-left:1em;font-weight:300;border-radius:0}.label-default{color:#333;background-color:#e7e7e7}.badge{font-weight:300}.progress{height:22px;padding:2px;background-color:#f6f6f6;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none}.dropdown-menu{padding:0;margin-top:0;font-size:12px}.dropdown-menu>li>a{padding:12px 15px}.dropdown-header{padding-right:15px;padding-left:15px;font-size:9px;text-transform:uppercase}.popover{font-size:12px;font-weight:300;color:#fff}.panel-heading,.panel-footer{border-top-right-radius:0;border-top-left-radius:0}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed} diff --git a/css/cinder.css b/css/cinder.css new file mode 100644 index 00000000..48345605 --- /dev/null +++ b/css/cinder.css @@ -0,0 +1,88 @@ +/* + Cinder Theme for MkDocs | Copyright 2015 Christopher Simpkins | MIT License +*/ + +body { + font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 1.7; + background-color: #FFF; + color: #343838; +} +h1, h2, h3, h4, h5, h6 { + font-family:'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; + color: #222; +} +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + color: #B1B7B9; +} + +h2 { + margin-top: 35px; +} + +h1, h2 { + font-weight: 700; +} +h4 { + font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 300; + margin-top: 20px; + font-style: italic; +} +h5 { + font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 300; + font-variant: small-caps; +} +pre, code { + background-color: #FCFDFF; +} +pre>code { + font-size: 13px; +} +pre { + margin-top: 25px; + margin-bottom: 25px; +} +.lead { + font-family:"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 400; + line-height: 1.4; + letter-spacing: 0.0312em; + color: #B1B7B9; +} +.navbar-default { + background-color: #343838; + border-bottom: 8px #EBF2F2 solid; +} +.bs-sidenav { + background-image: url("../img/grid11.png"); + background-repeat: repeat; + font-family: Inter,"Helvetica Neue",Helvetica,Arial,sans-serif; + font-size: 13px; +} +.well { + background-color: #FCFDFF; +} +.btn-default { + background-color:#FCFDFF; +} +.table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th { + background-color: #FCFDFF; +} +#mkdocs-search-query:focus { + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} +#mkdocs-search-query { + font-family:"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 20px; + font-weight: 700; + color: #343838; + height: 45px; +} +footer > hr { + width: 35%; +} diff --git a/css/cinder.min.css b/css/cinder.min.css new file mode 100644 index 00000000..fb7cc34f --- /dev/null +++ b/css/cinder.min.css @@ -0,0 +1 @@ +body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;line-height:1.7;background-color:#FFF;color:#343838}h1,h2,h3,h4,h5,h6{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;color:#222}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{color:#b1b7b9}h2{margin-top:35px}h1,h2{font-weight:700}h4{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;margin-top:20px;font-style:italic}h5{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;font-variant:small-caps}pre,code{background-color:#fcfdff}pre>code{font-size:13px}pre{margin-top:25px;margin-bottom:25px}.lead{font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:400;line-height:1.4;letter-spacing:.0312em;color:#b1b7b9}.navbar-default{background-color:#343838;border-bottom:8px #ebf2f2 solid}.bs-sidenav{background-image:url("../img/grid11.png");background-repeat:repeat;font-family:Inter,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px}.well{background-color:#fcfdff}.btn-default{background-color:#fcfdff}.table-striped>tbody>tr:nth-child(2n+1)>td,.table-striped>tbody>tr:nth-child(2n+1)>th{background-color:#fcfdff}#mkdocs-search-query:focus{outline:0;-webkit-box-shadow:none;box-shadow:none}#mkdocs-search-query{font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:20px;font-weight:700;color:#343838;height:45px}footer>hr{width:35%} diff --git a/css/highlight.css b/css/highlight.css new file mode 100644 index 00000000..a2b9270e --- /dev/null +++ b/css/highlight.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #FCFDFF; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/css/highlight.min.css b/css/highlight.min.css new file mode 100644 index 00000000..1b6ab941 --- /dev/null +++ b/css/highlight.min.css @@ -0,0 +1 @@ +.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#fcfdff}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:bold}.hljs-number,.hljs-literal,.hljs-variable,.hljs-template-variable,.hljs-tag .hljs-attr{color:teal}.hljs-string,.hljs-doctag{color:#d14}.hljs-title,.hljs-section,.hljs-selector-id{color:#900;font-weight:bold}.hljs-subst{font-weight:normal}.hljs-type,.hljs-class .hljs-title{color:#458;font-weight:bold}.hljs-tag,.hljs-name,.hljs-attribute{color:navy;font-weight:normal}.hljs-regexp,.hljs-link{color:#009926}.hljs-symbol,.hljs-bullet{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} diff --git a/effects/index.html b/effects/index.html new file mode 100644 index 00000000..83bdd31e --- /dev/null +++ b/effects/index.html @@ -0,0 +1,3216 @@ + + + + + + + + + + + + + + Layer Effects - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Layer Effects

+

Layers can have post-processing effects applied to them.

+

Effects

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
nmstring +

Name, as seen from editors and the like

+
mnstring +

Match name, used in expressions

+
efarray of Effect No Value or Effect Value Angle or Effect Value Checkbox or Effect Value Color or Effect Value Drop Down or Ignored Value or Effect Value Layer or Effect Value Point or Effect Value Slider +

Array of effect values. Each effect below shows a table with the values it expects.

+
npinteger +

Number of values in ef

+
ixinteger +

Effect Index

+
tyinteger +

Effect type

+
en0-1 integer +

Enabled

+
+
+

Many effects have unused values which are labeled with a number.

+

Effect types:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tyEffect Type
5Misc Effect
20Tint
21Fill
22Stroke
23Tritone
24Pro Levels
25Drop Shadow
26Radial Wipe
27Displacement Map
28Matte3
29Gaussian Blur
30Twirl
31Mesh Warp
32Wavy
33Spherize
34Puppet
+

All the examples will use this as their base:

+

+

+
+
+
+
+ +
+

+

Fill Effect

+

Fill all opaque areas with a solid color

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 21 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
00Effect Value Point
01Effect Value Drop Down
colorEffect Value Color
03Effect Value Drop Down
04Effect Value Slider
05Effect Value Slider
opacityEffect Value Slider
+
+ + + + + + + + + + + + + + + + + + + + +
1
Color
1
0.9
0
+
+
+
+
+ + +
+

Stroke Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 22 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
00Effect Value Color
01Effect Value Checkbox
02Effect Value Checkbox
colorEffect Value Color
04Effect Value Slider
05Effect Value Slider
06Effect Value Slider
07Effect Value Slider
08Effect Value Slider
09Effect Value Drop Down
typeEffect Value Drop Down
+

Tritone Effect

+

Converts the layer to greyscale, then applies the gradient based on bright/mid/dark.

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 23 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + +
NameType
brightEffect Value Color
midEffect Value Color
darkEffect Value Color
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bright
1
1
1
Mid
0.3
0.8
0.3
Dark
0
0
0
+
+
+
+
+ + +
+

Pro Levels Effect

+

Color correction levels. +For more information refer to the After Effects Documentation.

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 24 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
00Effect Value Drop Down
01Effect No Value
02Effect No Value
comp_inblackEffect Value Slider
comp_inwhiteEffect Value Slider
comp_gammaEffect Value Slider
comp_outblackEffect Value Slider
comp_outwhiteEffect No Value
08Effect No Value
09Effect Value Slider
r_inblackEffect Value Slider
r_inwhiteEffect Value Slider
r_gammaEffect Value Slider
r_outblackEffect Value Slider
r_outwhiteEffect Value Slider
15Effect Value Slider
16Effect Value Slider
g_inblackEffect Value Slider
g_inwhiteEffect Value Slider
g_gammaEffect Value Slider
g_outblackEffect Value Slider
g_outwhiteEffect Value Slider
22Effect Value Slider
23Effect Value Slider
b_inblackEffect Value Slider
b_inwhiteEffect Value Slider
b_gammaEffect Value Slider
b_outblackEffect Value Slider
b_outwhiteEffect Value Slider
29Effect Value Slider
a_inblackEffect Value Slider
a_inwhiteEffect Value Slider
a_gammaEffect Value Slider
a_outblackEffect Value Slider
a_outwhiteEffect No Value
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Composite
0
1
1
0
1
Red
0
1
1
0
1
Green
0
1
1
0
1
Blue
0
1
1
0
1
+
+
+
+
+ + +
+

Tint Effect

+

The layer is converted to grayscale, then black to white is mapped to +the given color.

+

The result is merged back with the original based on the intensity.

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 20 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + +
NameType
Black ColorEffect Value Color
White ColorEffect Value Color
IntensityEffect Value Slider
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Black
0
0
0
White
0
1
0
Intensity
90
+
+
+
+
+ + +
+

Matte3 Effect

+

Uses a layer as a mask

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 28 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
LayerEffect Value Layer
ChannelEffect Value Drop Down
InvertEffect Value Drop Down
Stretch To FitEffect Value Drop Down
Show MaskEffect Value Drop Down
Premultiply MaskEffect Value Drop Down
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + +
+

Gaussian Blur Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 29 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + +
NameType
sigmaEffect Value Slider
directionEffect Value Slider
wrapEffect Value Checkbox
+
+ + + + + + + + + + + + + +
25
+
+
+
+
+ + +
+

Drop Shadow Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 25 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
colorEffect Value Color
opacityEffect Value Slider
angleEffect Value Angle
distanceEffect Value Slider
blurEffect Value Slider
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0
0
0
128
135
10
7
+
+
+
+
+ + +
+

Radial Wipe Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 26 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
CompletionEffect Value Slider
Start AngleEffect Value Angle
Wipe CenterEffect Value Point
WipeEffect Value Slider
FeatherEffect Value Slider
+

Displacement Map Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 27 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
Displacement Map LayerEffect Value Layer
Use For Horizontal DisplacementEffect Value Drop Down
Max Horizontal DisplacementEffect Value Slider
Use For Vertical DisplacementEffect Value Drop Down
Max Vertical DisplacementEffect Value Slider
Displacement Map BehaviorEffect Value Drop Down
Edge BehaviorEffect Value Drop Down
Expand OutputEffect Value Drop Down
+

Mesh Warp Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 31 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
RowsEffect Value Slider
ColumnsEffect Value Slider
QualityEffect Value Slider
03Effect No Value
+

Puppet Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 34 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
Puppet EngineEffect Value Drop Down
Mesh Rotation RefinementEffect Value Slider
On TransparentEffect Value Drop Down
03Effect No Value
+

Spherize Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 33 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + +
NameType
radiusEffect Value Slider
centerEffect Value Point
+

Wavy Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 32 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameType
RadiusEffect Value Slider
CenterEffect Value Point
Conversion typeEffect Value Drop Down
SpeedEffect Value Drop Down
WidthEffect Value Slider
HeightEffect Value Slider
PhaseEffect Value Slider
+

Twirl Effect

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 30 +

Type

+
efarray +

Effect values

+
+
+ + + + + + + + + + + + + + + + + + + + + +
NameType
AngleEffect Value Angle
RadiusEffect Value Slider
CenterEffect Value Point
+

Custom Effect

+

You might find various different effects all with ty = 5.

+

Sometimes these are used together with expressions.

+
+ + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 5 +

Type

+
+
+

Effect Values

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
nmstring +

Name

+
mnstring +

Match Name

+
ixinteger +

Effect Index

+
tyinteger +

Type

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tyControl Type
0Slider
1Angle
2Color
3Point
4Checkbox
6Ignored
7Dropdown
10Layer
+

No Value

+
+

Slider

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 0 +

Type

+
vAnimated number +

Value

+
+
+

Angle

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 1 +

Type

+
vAnimated number +

Value

+
+
+

Color

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 2 +

Type

+
vAnimated Color +

Value

+
+
+

Point

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 3 +

Type

+
vAnimated Vector +

Value

+
+
+

Checkbox

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 4 +

Type

+
vAnimated number +

Value

+
+
+

Ignored

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 6 +

Type

+
vnumber +

Value

+
+
+ +
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 7 +

Type

+
vAnimated number +

Value

+
+
+

Layer

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 10 +

Type

+
vAnimated number +

Value

+
+
+

Layer Style

+

A layer can also have a list of styles applied to it

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
nmstring +

Name, as seen from editors and the like

+
mnstring +

Match name, used in expressions

+
tyinteger +

Style Type

+
+
+

Style types:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tyStyle Type
0Stroke
1Drop Shadow
2Inner Shadow
3Outer Glow
4Inner Glow
5Bevel / Emboss
6Satin
7Color Overlay
8Gradient Overlay
+

Stroke Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 0 +

Layer Type

+
sAnimated number +

Size

+
cAnimated Color +

Color

+
+
+

Drop Shadow Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 1 +

Layer Type

+
cAnimated Color +

Color

+
oAnimated number +

Opacity

+
aAnimated number +

Local light angle

+
sAnimated number +

Blur size

+
dAnimated number +

Distance

+
chAnimated number +

Choke Spread

+
bmAnimated number +

Blend Mode

+
noAnimated number +

Noise

+
lcAnimated number +

Layer knowck out drop shadow

+
+
+

Inner Shadow Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 2 +

Layer Type

+
cAnimated Color +

Color

+
oAnimated number +

Opacity

+
aAnimated number +

Local light angle

+
sAnimated number +

Blur size

+
dAnimated number +

Distance

+
chAnimated number +

Choke Spread

+
bmAnimated number +

Blend Mode

+
noAnimated number +

Noise

+
+
+

Outer Glow Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 3 +

Layer Type

+
cAnimated Color +

Color

+
oAnimated number +

Opacity

+
rAnimated number +

Range

+
chAnimated number +

Choke Spread

+
bmAnimated number +

Blend Mode

+
noAnimated number +

Noise

+
jAnimated number +

Jitter

+
+
+

Inner Glow Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 4 +

Layer Type

+
cAnimated Color +

Color

+
oAnimated number +

Opacity

+
rAnimated number +

Range

+
srAnimated number +

Source

+
chAnimated number +

Choke Spread

+
bmAnimated number +

Blend Mode

+
noAnimated number +

Noise

+
jAnimated number +

Jitter

+
+
+

Bevel / Emboss Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 5 +

Layer Type

+
bsAnimated number +

Bevel Style

+
btAnimated number +

Technique

+
srAnimated number +

Strength

+
sAnimated number +

Size

+
sfAnimated number +

Soften

+
gaAnimated number +

Use global light

+
aAnimated number +

Local lighting angle

+
llAnimated number +

Local lighting altitude

+
hmAnimated number +

Highlight Mode

+
hcAnimated Color +

Highlight Color

+
hoAnimated number +

Highlight Opacity

+
smAnimated number +

Shadow Mode

+
scAnimated Color +

Shadow Color

+
soAnimated number +

Shadow Opacity

+
+
+

Satin Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 6 +

Layer Type

+
bmAnimated number +

Blend Mode

+
cAnimated Color +

Color

+
oAnimated number +

Opacity

+
aAnimated number +

Angle

+
dAnimated number +

Distance

+
sAnimated number +

Size

+
inAnimated number +

Invert

+
+
+

Color Overlay Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 7 +

Layer Type

+
bmAnimated number +

Blend Mode

+
cAnimated Color +

Color

+
soAnimated number +

Opacity

+
+
+

Gradient Overlay Style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 8 +

Layer Type

+
bmAnimated number +

Blend Mode

+
oAnimated number +

Opacity

+
gfGradient Colors +

Gradient

+
gsAnimated number +

Smoothness

+
aAnimated number +

Angle

+
gtGradient Type +

Gradient Type

+
reAnimated number +

Reverse

+
alAnimated number +

Align with layer

+
sAnimated number +

Scale

+
ofAnimated number +

Offset

+
+
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/3d_layers.json b/examples/3d_layers.json new file mode 100644 index 00000000..d7a3c885 --- /dev/null +++ b/examples/3d_layers.json @@ -0,0 +1,194 @@ +{ + "v": "5.9.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 512, + "h": 512, + "nm": "3d layers", + "ddd": 1, + "layers": [ + { + "ddd": 1, + "ind": 2, + "ty": 4, + "nm": "Blue Circle", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "el", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.196, 0.314, 0.69] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ind": 2, + "ty": 4, + "nm": "Yellow Square", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 30 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 1, 0.3] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] +} diff --git a/examples/3d_layers_animation.json b/examples/3d_layers_animation.json new file mode 100644 index 00000000..f3b64405 --- /dev/null +++ b/examples/3d_layers_animation.json @@ -0,0 +1,273 @@ +{ + "v": "5.9.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 512, + "h": 512, + "nm": "3d layers", + "ddd": 1, + "layers": [ + { + "ddd": 1, + "ind": 2, + "ty": 4, + "nm": "Blue Circle", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.302 + ], + "y": [ + 1.121 + ] + }, + "o": { + "x": [ + 0.411 + ], + "y": [ + 0 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 75, + "s": [ + 180 + ] + } + ] + }, + "ry": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.288 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.685 + ], + "y": [ + 0 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 60, + "s": [ + -180 + ] + } + ] + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 1, + "k": [ + { + "i": { + "x": 0.667, + "y": 1 + }, + "o": { + "x": 0.333, + "y": 0 + }, + "t": 0, + "s": [ + 120, + 256, + 0 + ] + }, + { + "t": 75, + "s": [ + 400, + 256, + 200 + ] + } + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "el", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.196, 0.314, 0.69] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ind": 2, + "ty": 4, + "nm": "Yellow Square", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 30 + }, + "ry": { + "a": 0, + "k": 20 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256, + -1 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 1, 0.3] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] +} diff --git a/examples/3d_parenting.json b/examples/3d_parenting.json new file mode 100644 index 00000000..1302b078 --- /dev/null +++ b/examples/3d_parenting.json @@ -0,0 +1,909 @@ +{ + "v": "5.9.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 512, + "h": 512, + "nm": "3d layers", + "ddd": 1, + "layers": [ + { + "ddd": 1, + "ty": 13, + "nm": "Camera", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + -10 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "pe": {"a": 0, "k": 256} + }, + { + "ddd": 1, + "ty": 4, + "ind": 1, + "nm": "Parent", + "ks": { + "o": { + "a": 0, + "k": 50 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 1, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Front", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + 200 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.5, 0.5, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall FR", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 141, + 0, + 141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.5, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall FL", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": -45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -141, + 0, + 141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0, 0.5, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Left", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": -90 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -200, + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0, 0.5, 0.5] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Right", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 90 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 200, + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.5, 0.5] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall BR", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": -45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 141, + 0, + -141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.5, 0] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall BL", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -141, + 0, + -141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0, 0.5, 0] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Back", + "parent": 1, + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + -200 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.5, 0.5, 0] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] +} + diff --git a/examples/auto_orient.json b/examples/auto_orient.json new file mode 100644 index 00000000..ac4501e6 --- /dev/null +++ b/examples/auto_orient.json @@ -0,0 +1,390 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{46da3bdd-424c-4d87-ab48-70568860494c}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ + { + "nm": "PolyStar", + "id": "{e2e65917-0097-48d1-a5ae-17873a1ebb3e}", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "PolyStar", + "mn": "{2075ceec-ea0c-473d-9063-706380ba0a2c}", + "ks": { + "a": { + "a": 0, + "k": [ + 125.51641791044776, + 106.60298507462687 + ] + }, + "p": { + "a": 0, + "k": [ + 125.51641791044776, + 106.60298507462687 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 50 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{a3f805b0-34a3-4ccd-941e-5f84b407c0dd}", + "p": { + "a": 0, + "k": [ + 125.51641791044776, + 106.60298507462687 + ] + }, + "or": { + "a": 0, + "k": 73.93932342529297 + }, + "ir": { + "a": 0, + "k": 36.969661712646484 + }, + "r": { + "a": 0, + "k": 90 + }, + "pt": { + "a": 0, + "k": 3 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{c6d0521b-355c-4f8e-83e7-1c2814d3cfad}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + } + ] + } + ] + } +], +"layers": [ + { + "ty": 0, + "ddd": 0, + "nm": "Layer", + "mn": "{89b88968-ac5c-4e11-be47-b9ce60f5073e}", + "ip": 0, + "op": 180, + "ind": 1, + "st": 0, + "sr": 1, + "ao": 1, + "ks": { + "a": { + "a": 0, + "k": [ + 125.50000000000003, + 105.70000000000003 + ] + }, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 125.50000000000003, + 105.70000000000003 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 408.489552238806, + 110.89850746268658 + ] + }, + { + "t": 50, + "s": [ + 408.489552238806, + 110.89850746268658 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 107.85597014925375, + 410.49876865671655 + ] + }, + { + "t": 130, + "s": [ + 107.85597014925375, + 410.49876865671655 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 125.50000000000003, + 105.70000000000003 + ] + }, + { + "t": 180, + "s": [ + 125.50000000000003, + 105.70000000000003 + ] + } + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "refId": "{e2e65917-0097-48d1-a5ae-17873a1ebb3e}", + "w": 512, + "h": 512 + }, + { + "ty": 0, + "ddd": 0, + "nm": "Layer", + "mn": "{89b88968-ac5c-4e11-be47-b9ce60f5073e}", + "ip": 0, + "op": 180, + "ind": 2, + "st": 0, + "sr": 1, + "ks": { + "a": { + "a": 0, + "k": [ + 125.50000000000003, + 105.70000000000003 + ] + }, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 125.50000000000003, + 105.70000000000003 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 408.489552238806, + 110.89850746268658 + ] + }, + { + "t": 50, + "s": [ + 408.489552238806, + 110.89850746268658 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 107.85597014925375, + 410.49876865671655 + ] + }, + { + "t": 130, + "s": [ + 107.85597014925375, + 410.49876865671655 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 125.50000000000003, + 105.70000000000003 + ] + }, + { + "t": 180, + "s": [ + 125.50000000000003, + 105.70000000000003 + ] + } + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 50 + } + }, + "refId": "{e2e65917-0097-48d1-a5ae-17873a1ebb3e}", + "w": 512, + "h": 512 + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/bezier.json b/examples/bezier.json new file mode 100644 index 00000000..80a51b4e --- /dev/null +++ b/examples/bezier.json @@ -0,0 +1,135 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Group", + "it": [ + { + "ty": "sh", + "nm": "Shape", + "ks": { + "a": 0, + "k": { + "c": true, + "v": [], + "i": [], + "o": [] + } + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/bezier_expression.json b/examples/bezier_expression.json new file mode 100644 index 00000000..91919d4d --- /dev/null +++ b/examples/bezier_expression.json @@ -0,0 +1,682 @@ +{ + "nm": "Animation", + "fr": 60, + "ip": 0, + "op": 280, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [], + "chars": [], + "layers": [ + { + "nm": "Shapes", + "ddd": 0, + "hd": false, + "ks": {}, + "ao": 0, + "ip": 0, + "op": 280, + "st": 0, + "hasMask": false, + "masksProperties": [], + "ef": [ + { + "ef": [ + { + "ty": 0, + "nm": "Slider", + "v": { + "a": 1, + "k": [ + { + "t": 0, + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "s": [ + 0 + ] + }, + { + "t": 120, + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "s": [ + 1 + ] + }, + { + "t": 140, + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + }, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "s": [ + 1 + ] + }, + { + "t": 260, + "s": [ + 0 + ] + } + ] + } + } + ], + "ty": 5, + "nm": "Slider" + } + ], + "mb": false, + "ty": 4, + "shapes": [ + { + "nm": "Bezier Point", + "hd": false, + "ty": "gr", + "it": [ + { + "nm": "p0", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 25, + 400 + ], + "x": "var group = thisLayer.content(\"Linear Points\");\nvar pt_index = 0;\nvar pt_from = group.content(\"p\"+pt_index).position;\nvar pt_to = group.content(\"p\"+(pt_index+1)).position;\nvar t = thisLayer.effect(\"Slider\")(\"Slider\");\nvar $bm_rt = linear(t, pt_from, pt_to);\n" + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "hd": false, + "ty": "fl", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.125, + 0 + ] + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Linear Points", + "hd": false, + "ty": "gr", + "it": [ + { + "nm": "p0", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 25, + 400 + ], + "x": "var group = thisLayer.content(\"Quadratic Points\");\nvar pt_index = 0;\nvar pt_from = group.content(\"p\"+pt_index).position;\nvar pt_to = group.content(\"p\"+(pt_index+1)).position;\nvar t = thisLayer.effect(\"Slider\")(\"Slider\");\nvar $bm_rt = linear(t, pt_from, pt_to);\n" + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "nm": "p1", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 130, + 170 + ], + "x": "var group = thisLayer.content(\"Quadratic Points\");\nvar pt_index = 1;\nvar pt_from = group.content(\"p\"+pt_index).position;\nvar pt_to = group.content(\"p\"+(pt_index+1)).position;\nvar t = thisLayer.effect(\"Slider\")(\"Slider\");\nvar $bm_rt = linear(t, pt_from, pt_to);\n" + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "hd": false, + "ty": "fl", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.8, + 0 + ] + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Linear Lines", + "hd": false, + "ty": "gr", + "it": [ + { + "ty": "sh", + "ks": { + "a": 0, + "k": { + "i": [], + "o": [], + "v": [] + }, + "x": "var group = thisLayer.content(\"Linear Points\");\nvar num_points = 2;\nvar points = [];\nvar ip = [];\nvar op = [];\nfor ( var i = 0; i < num_points; i++ )\n{\n var pos = group.content(\"p\" + i).position;\n points.push(pos);\n ip.push(pos);\n op.push(pos);\n}\nvar $bm_rt = {\n v: points,\n i: ip,\n o: op\n};\n" + } + }, + { + "hd": false, + "ty": "st", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.8, + 0 + ] + }, + "w": { + "a": 0, + "k": 10 + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Quadratic Points", + "hd": false, + "ty": "gr", + "it": [ + { + "nm": "p0", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 25, + 400 + ], + "x": "var group = thisLayer.content(\"Cubic Points\");\nvar pt_index = 0;\nvar pt_from = group.content(\"p\"+pt_index).position;\nvar pt_to = group.content(\"p\"+(pt_index+1)).position;\nvar t = thisLayer.effect(\"Slider\")(\"Slider\");\nvar $bm_rt = linear(t, pt_from, pt_to);\n" + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "nm": "p1", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 130, + 170 + ], + "x": "var group = thisLayer.content(\"Cubic Points\");\nvar pt_index = 1;\nvar pt_from = group.content(\"p\"+pt_index).position;\nvar pt_to = group.content(\"p\"+(pt_index+1)).position;\nvar t = thisLayer.effect(\"Slider\")(\"Slider\");\nvar $bm_rt = linear(t, pt_from, pt_to);\n" + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "nm": "p2", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 350, + 230 + ], + "x": "var group = thisLayer.content(\"Cubic Points\");\nvar pt_index = 2;\nvar pt_from = group.content(\"p\"+pt_index).position;\nvar pt_to = group.content(\"p\"+(pt_index+1)).position;\nvar t = thisLayer.effect(\"Slider\")(\"Slider\");\nvar $bm_rt = linear(t, pt_from, pt_to);\n" + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "hd": false, + "ty": "fl", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.2, + 0.2, + 1 + ] + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Quadratic Lines", + "hd": false, + "ty": "gr", + "it": [ + { + "ty": "sh", + "ks": { + "a": 0, + "k": { + "i": [], + "o": [], + "v": [] + }, + "x": "var group = thisLayer.content(\"Quadratic Points\");\nvar num_points = 3;\nvar points = [];\nvar ip = [];\nvar op = [];\nfor ( var i = 0; i < num_points; i++ )\n{\n var pos = group.content(\"p\" + i).position;\n points.push(pos);\n ip.push(pos);\n op.push(pos);\n}\nvar $bm_rt = {\n v: points,\n i: ip,\n o: op\n};\n" + } + }, + { + "hd": false, + "ty": "st", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.2, + 0.2, + 1 + ] + }, + "w": { + "a": 0, + "k": 10 + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Cubic Points", + "hd": false, + "ty": "gr", + "it": [ + { + "nm": "p0", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 25, + 400 + ] + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "nm": "p1", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 130, + 170 + ] + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "nm": "p2", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 350, + 230 + ] + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "nm": "p3", + "hd": false, + "ty": "el", + "p": { + "a": 0, + "k": [ + 485, + 400 + ] + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "hd": false, + "ty": "fl", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Cubic Lines", + "hd": false, + "ty": "gr", + "it": [ + { + "ty": "sh", + "ks": { + "a": 0, + "k": { + "i": [], + "o": [], + "v": [] + }, + "x": "var group = thisLayer.content(\"Cubic Points\");\nvar num_points = 4;\nvar points = [];\nvar ip = [];\nvar op = [];\nfor ( var i = 0; i < num_points; i++ )\n{\n var pos = group.content(\"p\" + i).position;\n points.push(pos);\n ip.push(pos);\n op.push(pos);\n}\nvar $bm_rt = {\n v: points,\n i: ip,\n o: op\n};\n" + } + }, + { + "hd": false, + "ty": "st", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "w": { + "a": 0, + "k": 10 + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "nm": "Bezier Result", + "hd": false, + "ty": "gr", + "it": [ + { + "ty": "sh", + "ks": { + "a": 0, + "k": { + "i": [], + "o": [], + "v": [] + }, + "x": "var group = thisLayer.content(\"Cubic Points\");\nvar $bm_rt = {\n v: [group.content(\"p0\").position, group.content(\"p3\").position],\n i: [[0, 0], group.content(\"p2\").position],\n o: [group.content(\"p1\").position, [0,0]]\n};\n" + } + }, + { + "hd": false, + "ty": "st", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.8, + 0 + ] + }, + "w": { + "a": 0, + "k": 10 + } + }, + { + "hd": false, + "ty": "tr", + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } + ] +} diff --git a/examples/blend_mode.json b/examples/blend_mode.json new file mode 100644 index 00000000..9d9a5a6a --- /dev/null +++ b/examples/blend_mode.json @@ -0,0 +1,533 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{429ff333-f31c-4124-91c5-5e861412a004}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 1, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{625eab7e-4758-4d4b-b37c-d89115b1442b}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 50 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Ellipse", + "mn": "{dd57d763-ff3b-420f-a94d-eb5503e7faa7}", + "it": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{fa5c495c-00d1-4253-b30c-cc8cb1b855b2}", + "p": { + "a": 0, + "k": [ + 400.1910447761194, + 240.71641791044777 + ] + }, + "s": { + "a": 0, + "k": [ + 195.15223880597017, + 180.53731343283584 + ] + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{89437b5f-dca9-42d4-aff9-c57ce08c8c1e}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{352559ca-ebe9-4b11-acdd-09e155612598}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.3411764705882353, + 0.01568627450980392 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 400.1910447761194, + 240.71641791044777 + ] + }, + "p": { + "a": 0, + "k": [ + 400.1910447761194, + 240.71641791044777 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{b6000853-a4d3-4b13-acdd-2e4f1a192760}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{d647a149-8105-4e08-b395-c8de40669fb0}", + "p": { + "a": 0, + "k": [ + 110.90149253731343, + 216.644776119403 + ] + }, + "or": { + "a": 0, + "k": 121.5619125366211 + }, + "ir": { + "a": 0, + "k": 60.78095626831055 + }, + "r": { + "a": 0, + "k": 143.04905700683594 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{67a87e2b-afff-4f55-9004-4cc274cefe07}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{39b8d13c-45cf-4ad7-972a-ef5169f1ffbf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 110.90149253731343, + 216.644776119403 + ] + }, + "p": { + "a": 0, + "k": [ + 159.9044776119403, + 247.59402985074627 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer 1", + "mn": "{d74c9dcc-e7af-45c3-9eab-554c7b93f6b6}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Rectangle 1", + "mn": "{b22ddad1-738b-471a-86eb-1f072fa45799}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle 1", + "mn": "{0c09bd21-59ab-4f1e-bd3d-547613eb3e2a}", + "p": { + "a": 0, + "k": [ + 241.57611940298506, + 357.6358208955224 + ] + }, + "s": { + "a": 0, + "k": [ + 383.4268656716418, + 211.4865671641791 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{8cd4fca9-3480-49fa-947f-04bc40ed74f5}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{050089d8-44c4-4312-8e23-3c89df7615aa}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.7686274509803922, + 0.8509803921568627, + 0.9607843137254902 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 241.57611940298506, + 357.6358208955224 + ] + }, + "p": { + "a": 0, + "k": [ + 226.1014925373134, + 131.53432835820894 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "gr", + "nm": "Rectangle", + "mn": "{700bfca8-0e45-42e9-8559-15ac0ebe93b2}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{0e3ac2ac-22c8-4310-8208-f5d5ba9cd6d9}", + "p": { + "a": 0, + "k": [ + 277.68358208955226, + 148.2985074626866 + ] + }, + "s": { + "a": 0, + "k": [ + 335.2835820895522, + 162.48358208955224 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{af0c691f-7815-414e-a988-ac2eb6e32128}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{059d8c4e-de02-4fa7-99fe-c069b73218be}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 277.68358208955226, + 148.2985074626866 + ] + }, + "p": { + "a": 0, + "k": [ + 277.68358208955226, + 366.6626865671642 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/blep.png b/examples/blep.png new file mode 100644 index 00000000..23dbec74 Binary files /dev/null and b/examples/blep.png differ diff --git a/examples/bouncy_ball.json b/examples/bouncy_ball.json new file mode 100644 index 00000000..efc88496 --- /dev/null +++ b/examples/bouncy_ball.json @@ -0,0 +1,232 @@ +{ + "nm": "Bouncy Ball", + "v": "5.5.2", + "ip": 0, + "op": 120, + "fr": 60, + "w": 512, + "h": 512, + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 120, + "nm": "Layer", + "ks": { + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Ellipse Group", + "it": [ + { + "ty": "el", + "nm": "Ellipse", + "p": { + "a": 0, + "k": [ + 204, + 169 + ] + }, + "s": { + "a": 0, + "k": [ + 153, + 153 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.710, + 0.192, + 0.278 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 204, + 169 + ] + }, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 235, + 106 + ], + "h": 0, + "o": { + "x": [ + 0.333 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 265, + 441 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 0.667 + ], + "y": [ + 1 + ] + } + }, + { + "t": 120, + "s": [ + 235, + 106 + ] + } + ] + }, + "s": { + "a": 1, + "k": [ + { + "t": 55, + "s": [ + 100, + 100 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 136, + 59 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 65, + "s": [ + 100, + 100 + ] + } + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } + ] +} diff --git a/examples/camera.json b/examples/camera.json new file mode 100644 index 00000000..0fc2696a --- /dev/null +++ b/examples/camera.json @@ -0,0 +1,899 @@ +{ + "v": "5.9.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 512, + "h": 512, + "nm": "3d layers", + "ddd": 1, + "layers": [ + { + "ddd": 1, + "ty": 13, + "nm": "Camera", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + -10 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "pe": {"a": 0, "k": 256} + }, + { + "ddd": 1, + "ty": 4, + "nm": "Page", + "ks": { + "o": { + "a": 0, + "k": 50 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 1, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Front", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + 200 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.5, 0.5, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall FR", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 141, + 0, + 141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.5, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall FL", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": -45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -141, + 0, + 141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0, 0.5, 1] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Left", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": -90 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -200, + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0, 0.5, 0.5] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Right", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 90 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 200, + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.5, 0.5] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall BR", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": -45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 141, + 0, + -141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [1, 0.5, 0] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall BL", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 45 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -141, + 0, + -141 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0, 0.5, 0] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ddd": 1, + "ty": 4, + "nm": "Wall Back", + "ks": { + "o": { + "a": 0, + "k": 100 + }, + "rx": { + "a": 0, + "k": 0 + }, + "ry": { + "a": 0, + "k": 0 + }, + "rz": { + "a": 0, + "k": 0 + }, + "or": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0, + -200 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } + }, + "ip": 0, + "op": 120, + "st": 0, + "shapes": [ + { + "ty": "rc", + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [0.5, 0.5, 0] + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] +} diff --git a/examples/easing.json b/examples/easing.json new file mode 100644 index 00000000..4c7ff852 --- /dev/null +++ b/examples/easing.json @@ -0,0 +1,425 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{95dd568f-a39c-460e-a8c7-e0637125ea5b}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ + { + "id": "{d74d055a-03d0-4fbf-93f1-bddaad919dae}", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ip": 0, + "op": 180, + "ind": 1, + "st": 0, + "ks": { + }, + "shapes": [ + { + "ty": "el", + "nm": "Ellipse 2", + "mn": "{703940be-b224-44bb-a545-f7c29fdf1e41}", + "p": { + "a": 0, + "k": [ + 0.333, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 0.05, + 0.05 + ] + } + }, + { + "ty": "el", + "nm": "Ellipse 1", + "mn": "{c0236cd6-7f68-4fca-a5db-cf1485b59557}", + "p": { + "a": 0, + "k": [ + 0.67, + 1 + ] + }, + "s": { + "a": 0, + "k": [ + 0.05, + 0.05 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{d16479da-c98f-45fc-b286-1b59eadf437b}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.1607843137254902, + 0.1843137254901961, + 0.4588235294117647 + ] + }, + "r": 1 + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{bc8f2898-b708-426d-80bc-0d2c2c95fe85}", + "ks": { + }, + "shapes": [ + { + "ty": "sh", + "nm": "Path", + "mn": "{b3d15be6-88ad-4edf-aae5-2494cb33d424}", + "ks": { + "a": 0, + "k": { + "c": false, + "v": [ + [ + -0.33, + 0 + ], + [ + 0, + 0 + ], + [ + 1, + 1 + ], + [ + 0.67, + 1 + ] + ], + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.33, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0.33, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ] + } + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{6b6fe0de-27f9-4e99-a417-756503dedaf3}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 0.01 + } + }, + { + "ty": "st", + "nm": "Stroke 1", + "mn": "{025fae60-2c9c-46b8-9c79-a41c9522f8d9}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.1607843137254902, + 0.1843137254901961, + 0.4588235294117647 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 0.015 + } + } + ] + } + ] + } +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ip": 0, + "op": 180, + "ind": 3, + "st": 0, + "ks": { + "a": { + "a": 0, + "k": [ + 65, + 65 + ] + }, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 65, + 65 + ], + "h": 0, + "o": { + "x": [ + 0.33, + 0.33 + ], + "y": [ + 0, + 0 + ] + }, + "i": { + "x": [ + 0.67, + 0.67 + ], + "y": [ + 1, + 1 + ] + } + }, + { + "t": 90, + "s": [ + 447, + 65 + ], + "h": 0, + "o": { + "x": [ + 0.33, + 0.33 + ], + "y": [ + 0, + 0 + ] + }, + "i": { + "x": [ + 0.67, + 0.67 + ], + "y": [ + 1, + 1 + ] + } + }, + { + "t": 180, + "s": [ + 65, + 65 + ] + } + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{1737ee49-c0c0-4c5f-9989-a99f644cd2e6}", + "p": { + "a": 0, + "k": [ + 65, + 65 + ] + }, + "s": { + "a": 0, + "k": [ + 120, + 120 + ] + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{a9596faa-7beb-4ee4-b8f6-59b676ace428}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.403921568627451, + 0.050980392156862744, + 0.01568627450980392 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 10 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{27782706-9dc4-4918-9476-4e544d2bfe0a}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ] + }, + "r": 1 + } + ] + }, + { + "ty": 0, + "ddd": 0, + "nm": "Composition Layer", + "mn": "{bcdc556f-2ca5-4c71-9849-c27e3b72470e}", + "ip": 0, + "op": 180, + "ind": 2, + "st": 0, + "sr": 1, + "ks": { + "a": { + "a": 0, + "k": [ + 0, + 0.5 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 51200, + -51200 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "refId": "{d74d055a-03d0-4fbf-93f1-bddaad919dae}", + "w": 512, + "h": 512 + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/effects-blur.json b/examples/effects-blur.json new file mode 100644 index 00000000..f2fcc748 --- /dev/null +++ b/examples/effects-blur.json @@ -0,0 +1,101 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 29, + "en": 1, + "ef": [ + { + "ty": 0, + "v": { + "a": 0, + "k": 25 + } + }, + { + "ty": 0, + "v": { + "k": 0, + "a": 0 + } + }, + { + "ty": 4, + "v": { + "k": 0, + "a": 0 + } + } + ] + } + ], + "refId": "blep" + } + ] +} diff --git a/examples/effects-bulge.json b/examples/effects-bulge.json new file mode 100644 index 00000000..e2aaa00a --- /dev/null +++ b/examples/effects-bulge.json @@ -0,0 +1,173 @@ +{ + "v": "5.9.0", + "fr": 60, + "ip": 0, + "op": 1800, + "w": 512, + "h": 512, + "nm": "Comp 1", + "ddd": 0, + "assets": [ + { + "id": "image_0", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 2, + "nm": "blep.png", + "cl": "png", + "refId": "image_0", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 256, + 256, + 0 + ], + "ix": 2, + "l": 2 + }, + "a": { + "a": 0, + "k": [ + 256, + 256, + 0 + ], + "ix": 1, + "l": 2 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Bulge", + "np": 9, + "mn": "ADBE Bulge", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 0, + "nm": "Horizontal Radius", + "mn": "ADBE Bulge-0001", + "ix": 1, + "v": { + "a": 0, + "k": 197, + "ix": 1 + } + }, + { + "ty": 0, + "nm": "Vertical Radius", + "mn": "ADBE Bulge-0002", + "ix": 2, + "v": { + "a": 0, + "k": 179, + "ix": 2 + } + }, + { + "ty": 3, + "nm": "Bulge Center", + "mn": "ADBE Bulge-0003", + "ix": 3, + "v": { + "a": 0, + "k": [ + 286, + 277 + ], + "ix": 3 + } + }, + { + "ty": 0, + "nm": "Bulge Height", + "mn": "ADBE Bulge-0004", + "ix": 4, + "v": { + "a": 0, + "k": 1.85, + "ix": 4 + } + }, + { + "ty": 0, + "nm": "Taper Radius", + "mn": "ADBE Bulge-0005", + "ix": 5, + "v": { + "a": 0, + "k": 0, + "ix": 5 + } + }, + { + "ty": 7, + "nm": "Antialiasing (Best Qual Only)", + "mn": "ADBE Bulge-0006", + "ix": 6, + "v": { + "a": 0, + "k": 1, + "ix": 6 + } + }, + { + "ty": 7, + "nm": "Pinning", + "mn": "ADBE Bulge-0007", + "ix": 7, + "v": { + "a": 0, + "k": 1, + "ix": 7 + } + } + ] + } + ], + "ip": 0, + "op": 1800, + "st": 0, + "bm": 0 + } + ], + "markers": [ + + ] +} diff --git a/examples/effects-fill.json b/examples/effects-fill.json new file mode 100644 index 00000000..90864711 --- /dev/null +++ b/examples/effects-fill.json @@ -0,0 +1,150 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 21, + "ef": [ + { + "ty": 3, + "v": { + "k": [ + 0, + 0 + ], + "a": 0 + } + }, + { + "ty": 7, + "v": { + "k": 0, + "a": 0 + } + }, + { + "ty": 2, + "v": { + "k": [ + 1, + 0.9, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 2, + "v": { + "k": [ + 0, + 0, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 7, + "v": { + "k": 0, + "a": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + } + ] + } + ], + "refId": "blep" + } + ] +} + + diff --git a/examples/effects-matte3-image.json b/examples/effects-matte3-image.json new file mode 100644 index 00000000..1bb52634 --- /dev/null +++ b/examples/effects-matte3-image.json @@ -0,0 +1,131 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + }, + { + "id": "thumbs-up", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/thumbs-up.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": {}, + "ip": 0, + "op": 60, + "st": 0, + "ind": 0, + "ef": [ + { + "ty": 28, + "nm": "Set Matte", + "np": 8, + "mn": "ADBE Set Matte3", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 10, + "nm": "Take Matte From Layer", + "mn": "ADBE Set Matte3-0001", + "ix": 1, + "v": { + "a": 0, + "k": 1, + "ix": 1 + } + }, + { + "ty": 7, + "nm": "Use For Matte", + "mn": "ADBE Set Matte3-0002", + "ix": 2, + "v": { + "a": 0, + "k": 4, + "ix": 2 + } + }, + { + "ty": 7, + "nm": "Invert Matte", + "mn": "ADBE Set Matte3-0003", + "ix": 3, + "v": { + "a": 0, + "k": 0, + "ix": 3 + } + }, + { + "ty": 7, + "nm": "If Layer Sizes Differ", + "mn": "ADBE Set Matte3-0004", + "ix": 4, + "v": { + "a": 0, + "k": 1, + "ix": 4 + } + }, + { + "ty": 7, + "nm": "Composite Matte with Original", + "mn": "ADBE Set Matte3-0005", + "ix": 5, + "v": { + "a": 0, + "k": 1, + "ix": 5 + } + }, + { + "ty": 7, + "nm": "Premultiply Matte Layer", + "mn": "ADBE Set Matte3-0006", + "ix": 6, + "v": { + "a": 0, + "k": 1, + "ix": 6 + } + } + ] + } + ], + "refId": "blep" + }, + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": {}, + "ip": 0, + "op": 60, + "st": 0, + "ind": 1, + "refId": "thumbs-up" + } + ] +} + + diff --git a/examples/effects-matte3.json b/examples/effects-matte3.json new file mode 100644 index 00000000..4227fc50 --- /dev/null +++ b/examples/effects-matte3.json @@ -0,0 +1,664 @@ +{ + "v": "5.9.0", + "fr": 29.9700012207031, + "ip": 0, + "op": 900.000036657751, + "w": 1920, + "h": 1080, + "nm": "Comp 1", + "ddd": 0, + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Star", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 960, + 540, + 0 + ], + "ix": 2, + "l": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ], + "ix": 1, + "l": 2 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "ef": [ + { + "ty": 28, + "nm": "Set Matte", + "np": 8, + "mn": "ADBE Set Matte3", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 10, + "nm": "Take Matte From Layer", + "mn": "ADBE Set Matte3-0001", + "ix": 1, + "v": { + "a": 0, + "k": 3, + "ix": 1 + } + }, + { + "ty": 7, + "nm": "Use For Matte", + "mn": "ADBE Set Matte3-0002", + "ix": 2, + "v": { + "a": 0, + "k": 1, + "ix": 2 + } + }, + { + "ty": 7, + "nm": "Invert Matte", + "mn": "ADBE Set Matte3-0003", + "ix": 3, + "v": { + "a": 0, + "k": 0, + "ix": 3 + } + }, + { + "ty": 7, + "nm": "If Layer Sizes Differ", + "mn": "ADBE Set Matte3-0004", + "ix": 4, + "v": { + "a": 0, + "k": 1, + "ix": 4 + } + }, + { + "ty": 7, + "nm": "Composite Matte with Original", + "mn": "ADBE Set Matte3-0005", + "ix": 5, + "v": { + "a": 0, + "k": 1, + "ix": 5 + } + }, + { + "ty": 7, + "nm": "Premultiply Matte Layer", + "mn": "ADBE Set Matte3-0006", + "ix": 6, + "v": { + "a": 0, + "k": 1, + "ix": 6 + } + } + ] + } + ], + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "sr", + "sy": 1, + "d": 1, + "pt": { + "a": 0, + "k": 5, + "ix": 3 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 4 + }, + "r": { + "a": 0, + "k": 222.865, + "ix": 5 + }, + "ir": { + "a": 0, + "k": 226.442, + "ix": 6 + }, + "is": { + "a": 0, + "k": 0, + "ix": 8 + }, + "or": { + "a": 0, + "k": 452.885, + "ix": 7 + }, + "os": { + "a": 0, + "k": 0, + "ix": 9 + }, + "ix": 1, + "nm": "Polystar Path 1", + "mn": "ADBE Vector Shape - Star", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 124, + -148 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Polystar 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 900.000036657751, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 4, + "nm": "Ellipse", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 960, + 540, + 0 + ], + "ix": 2, + "l": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ], + "ix": 1, + "l": 2 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { + "a": 0, + "k": [ + 528.102, + 545.938 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "nm": "Ellipse Path 1", + "mn": "ADBE Vector Shape - Ellipse", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 1, + 1, + 1, + 1 + ], + "ix": 3 + }, + "o": { + "a": 0, + "k": 100, + "ix": 4 + }, + "w": { + "a": 0, + "k": 2, + "ix": 5 + }, + "lc": 1, + "lj": 1, + "ml": 4, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.7686274509803922, + 0.8509803921568627, + 0.9607843137254902 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 409.91, + -95.102 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Ellipse 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 900.000036657751, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 3, + "ty": 4, + "nm": "Rectangle", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 960, + 540, + 0 + ], + "ix": 2, + "l": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ], + "ix": 1, + "l": 2 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ty": "rc", + "d": 1, + "s": { + "a": 0, + "k": [ + 78.482, + 70.992 + ], + "ix": 2 + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 4 + }, + "nm": "Rectangle Path 1", + "mn": "ADBE Vector Shape - Rect", + "hd": false + }, + { + "ty": "st", + "c": { + "a": 0, + "k": [ + 1, + 1, + 1, + 1 + ], + "ix": 3 + }, + "o": { + "a": 0, + "k": 100, + "ix": 4 + }, + "w": { + "a": 0, + "k": 2, + "ix": 5 + }, + "lc": 1, + "lj": 1, + "ml": 4, + "bm": 0, + "nm": "Stroke 1", + "mn": "ADBE Vector Graphic - Stroke", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + -143.321, + -63.043 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 563.332, + 416.105 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Rectangle 1", + "np": 3, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 900.000036657751, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} diff --git a/examples/effects-prolevels.json b/examples/effects-prolevels.json new file mode 100644 index 00000000..835e938a --- /dev/null +++ b/examples/effects-prolevels.json @@ -0,0 +1,361 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 24, + "ef": [ + { + "ty": 7, + "v": { + "nm": "00 Dropdown", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "01", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "02", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "comp_inblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "comp_inwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "comp_gamma slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "comp_outblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "comp_outwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "08", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "09 slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "r_inblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "r_inwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "r_gamma slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "r_outblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "r_outwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "15 slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "16 slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "g_inblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "g_inwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "g_gamma slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "g_outblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "g_outwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "22", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "23", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "b_inblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "b_inwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "b_gamma slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "b_outblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "b_outwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "29", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "a_inblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "a_inwhite slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "a_gamma slider", + "a": 0, + "k": 1 + } + }, + { + "ty": 0, + "v": { + "nm": "a_outblack slider", + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "nm": "a_outwhite slider", + "a": 0, + "k": 1 + } + } + ] + } + ], + "refId": "blep" + } + ] +} + + diff --git a/examples/effects-shadow.json b/examples/effects-shadow.json new file mode 100644 index 00000000..f28a2f57 --- /dev/null +++ b/examples/effects-shadow.json @@ -0,0 +1,119 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 25, + "ef": [ + { + "ty": 2, + "v": { + "k": [ + 0, + 0, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 0, + "v": { + "k": 128, + "a": 0 + } + }, + { + "ty": 1, + "v": { + "k": 135, + "a": 0 + } + }, + { + "ty": 0, + "v": { + "k": 10, + "a": 0 + } + }, + { + "ty": 0, + "v": { + "k": 7, + "a": 0 + } + } + ] + } + ], + "refId": "blep" + } + ] +} diff --git a/examples/effects-stroke.json b/examples/effects-stroke.json new file mode 100644 index 00000000..af296458 --- /dev/null +++ b/examples/effects-stroke.json @@ -0,0 +1,169 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 22, + "ef": [ + { + "ty": 2, + "v": { + "k": [ + 0, + 0, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 4, + "v": { + "k": 0, + "a": 0 + } + }, + { + "ty": 4, + "v": { + "k": 0, + "a": 0 + } + }, + { + "ty": 2, + "v": { + "k": [ + 1, + 0.9, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 0, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 7, + "v": { + "a": 0, + "k": 0 + } + }, + { + "ty": 7, + "v": { + "a": 0, + "k": 0 + } + } + ] + } + ], + "refId": "blep" + } + ] +} + + + diff --git a/examples/effects-tint.json b/examples/effects-tint.json new file mode 100644 index 00000000..287ce9fb --- /dev/null +++ b/examples/effects-tint.json @@ -0,0 +1,110 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 20, + "ef": [ + { + "ty": 2, + "v": { + "k": [ + 0, + 0, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 2, + "v": { + "k": [ + 0, + 1, + 0, + 1 + ], + "a": 0 + } + }, + { + "ty": 0, + "v": { + "k": 90, + "a": 0 + } + } + ] + } + ], + "refId": "blep" + } + ] +} diff --git a/examples/effects-tritone.json b/examples/effects-tritone.json new file mode 100644 index 00000000..f593ab30 --- /dev/null +++ b/examples/effects-tritone.json @@ -0,0 +1,116 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "ef": [ + { + "ty": 23, + "ef": [ + { + "ty": 2, + "v": { + "k": [ + 1, + 1, + 1, + 1 + ], + "a": 0 + } + }, + { + "ty": 2, + "v": { + "k": [ + 0.3, + 0.8, + 0.3, + 1 + ], + "a": 0 + } + }, + { + "ty": 2, + "v": { + "k": [ + 0, + 0, + 0, + 1 + ], + "a": 0 + } + } + ] + } + ], + "refId": "blep" + } + ] +} + diff --git a/examples/effects-wave.json b/examples/effects-wave.json new file mode 100644 index 00000000..40884733 --- /dev/null +++ b/examples/effects-wave.json @@ -0,0 +1,181 @@ +{ + "v": "5.9.0", + "fr": 60, + "ip": 0, + "op": 1800, + "w": 512, + "h": 512, + "nm": "Comp 1", + "ddd": 0, + "assets": [ + { + "id": "image_0", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 2, + "nm": "blep.png", + "cl": "png", + "refId": "image_0", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 256, + 256, + 0 + ], + "ix": 2, + "l": 2 + }, + "a": { + "a": 0, + "k": [ + 256, + 256, + 0 + ], + "ix": 1, + "l": 2 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6, + "l": 2 + } + }, + "ao": 0, + "ef": [ + { + "ty": 5, + "nm": "Wave Warp", + "np": 10, + "mn": "ADBE Wave Warp", + "ix": 1, + "en": 1, + "ef": [ + { + "ty": 7, + "nm": "Wave Type", + "mn": "ADBE Wave Warp-0001", + "ix": 1, + "v": { + "a": 0, + "k": 1, + "ix": 1 + } + }, + { + "ty": 0, + "nm": "Wave Height", + "mn": "ADBE Wave Warp-0002", + "ix": 2, + "v": { + "a": 0, + "k": 10, + "ix": 2 + } + }, + { + "ty": 0, + "nm": "Wave Width", + "mn": "ADBE Wave Warp-0003", + "ix": 3, + "v": { + "a": 0, + "k": 64, + "ix": 3 + } + }, + { + "ty": 0, + "nm": "Direction", + "mn": "ADBE Wave Warp-0004", + "ix": 4, + "v": { + "a": 0, + "k": 90, + "ix": 4 + } + }, + { + "ty": 7, + "nm": "Wave Speed", + "mn": "ADBE Wave Warp-0005", + "ix": 5, + "v": { + "a": 0, + "k": 2, + "ix": 5 + } + }, + { + "ty": 7, + "nm": "Pinning", + "mn": "ADBE Wave Warp-0006", + "ix": 6, + "v": { + "a": 0, + "k": 1, + "ix": 6 + } + }, + { + "ty": 0, + "nm": "Phase", + "mn": "ADBE Wave Warp-0007", + "ix": 7, + "v": { + "a": 0, + "k": 0, + "ix": 7 + } + }, + { + "ty": 7, + "nm": "Antialiasing (Best Quality)", + "mn": "ADBE Wave Warp-0008", + "ix": 8, + "v": { + "a": 0, + "k": 1, + "ix": 8 + } + } + ] + } + ], + "ip": 0, + "op": 1800, + "st": 0, + "bm": 0 + } + ], + "markers": [ + + ] +} diff --git a/examples/ellipse.json b/examples/ellipse.json new file mode 100644 index 00000000..4e4a765c --- /dev/null +++ b/examples/ellipse.json @@ -0,0 +1,142 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Group", + "it": [ + { + "ty": "el", + "nm": "Ellipse", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 256, + 256 + ] + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} + + diff --git a/examples/fill.json b/examples/fill.json new file mode 100644 index 00000000..07676a25 --- /dev/null +++ b/examples/fill.json @@ -0,0 +1,194 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{f5d94f54-bb8f-4f07-be45-232ebd4b9eb1}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{4b0993ed-e35b-48a5-ab12-687dbc147c7c}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Path", + "mn": "{29196ff2-0a65-48b4-a450-f9fbc3a3640d}", + "it": [ + { + "ty": "sh", + "nm": "Path", + "mn": "{bb7e6c60-755e-4a21-a7ba-bd054feab5c7}", + "ks": { + "a": 0, + "k": { + "c": true, + "v": [ + [ + 125.51641791044776, + 452.20298507462684 + ], + [ + 240.71641791044777, + 38.6865671641791 + ], + [ + 435.8686567164179, + 447.9044776119403 + ], + [ + 42.125373134328356, + 173.65970149253732 + ], + [ + 460.8, + 156.46567164179103 + ] + ], + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ] + } + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{3af40b83-15f6-4f69-aa2a-96acd03eb3b6}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.98, + 0.28 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 251.46268656716418, + 245.4447761194029 + ] + }, + "p": { + "a": 0, + "k": [ + 251.46268656716418, + 245.4447761194029 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/font-css.json b/examples/font-css.json new file mode 100644 index 00000000..59a76b27 --- /dev/null +++ b/examples/font-css.json @@ -0,0 +1,118 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 300, + "h": 100, + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "fPath": "https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap", + "fFamily": "Poppins", + "fStyle": "Bold", + "fName": "Poppins Bold", + "origin": 1 + } + ] + }, + "layers": [ + { + "ddd": 0, + "ty": 5, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 5, + 80 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 120, + "st": 0, + "bm": 0, + "ind": 0, + "t": { + "a": [], + "d": { + "k": [ + { + "s": { + "f": "Poppins Bold", + "fc": [ + 0, + 0, + 0, + 1 + ], + "s": 100, + "t": "Hello", + "j": 0 + }, + "t": 0 + } + ] + }, + "m": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + } + }, + "p": {} + } + }, + { + "ty": 1, + "sr": 1, + "ks": {}, + "ip": 0, + "op": 120, + "st": 0, + "sc": "#ffffff", + "sw": 300, + "sh": 100 + } + ] +} + + diff --git a/examples/font-local.json b/examples/font-local.json new file mode 100644 index 00000000..2ab68032 --- /dev/null +++ b/examples/font-local.json @@ -0,0 +1,116 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 300, + "h": 100, + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "fFamily": "monospace", + "fName": "MyFont", + "fStyle": "Regular", + "origin": 0 + } + ] + }, + "layers": [ + { + "ddd": 0, + "ty": 5, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 5, + 80 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 120, + "st": 0, + "bm": 0, + "ind": 0, + "t": { + "a": [], + "d": { + "k": [ + { + "s": { + "f": "MyFont", + "fc": [ + 0, + 0, + 0, + 1 + ], + "s": 100, + "t": "Hello", + "j": 0 + }, + "t": 0 + } + ] + }, + "m": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + } + }, + "p": {} + } + }, + { + "ty": 1, + "sr": 1, + "ks": {}, + "ip": 0, + "op": 120, + "st": 0, + "sc": "#ffffff", + "sw": 300, + "sh": 100 + } + ] +} + diff --git a/examples/font-url.json b/examples/font-url.json new file mode 100644 index 00000000..bad702ec --- /dev/null +++ b/examples/font-url.json @@ -0,0 +1,119 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 300, + "h": 100, + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "fPath": "https://fonts.gstatic.com/s/ubuntu/v15/4iCp6KVjbNBYlgoKejZftWyI.ttf", + "fFamily": "Ubuntu", + "fStyle": "Light Italic", + "fName": "Ubuntu Light Italic", + "origin": 3 + } + ] + }, + "layers": [ + { + "ddd": 0, + "ty": 5, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 5, + 80 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 120, + "st": 0, + "bm": 0, + "ind": 0, + "t": { + "a": [], + "d": { + "k": [ + { + "s": { + "f": "Ubuntu Light Italic", + "fc": [ + 0, + 0, + 0, + 1 + ], + "s": 100, + "t": "Hello", + "j": 0 + }, + "t": 0 + } + ] + }, + "m": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + } + }, + "p": {} + } + }, + { + "ty": 1, + "sr": 1, + "ks": {}, + "ip": 0, + "op": 120, + "st": 0, + "sc": "#ffffff", + "sw": 300, + "sh": 100 + } + ] +} + + + diff --git a/examples/fractal.json b/examples/fractal.json new file mode 100644 index 00000000..8fedc7ea --- /dev/null +++ b/examples/fractal.json @@ -0,0 +1,1403 @@ +{ + "v": "5.5.2", + "fr": 30, + "ip": 0, + "op": 100, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "precomp_0", + "layers": [ + { + "ddd": 0, + "ty": 4, + "sr": 1, + "ks": { + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 0, + "shapes": [ + { + "ty": "sh", + "d": 0, + "ks": { + "k": [ + { + "t": 0, + "i": {"x": [0.5], "y": [1]}, + "o": {"x": [0.5], "y": [0]}, + "s": [ + { + "c": false, + "i": [[0,0],[0,0],[0,0],[0,0],[0,0]], + "o": [[0,0],[0,0],[0,0],[0,0],[0,0]], + "v": [ + [ + 128, + 170.667 + ], + [ + 208, + 170.667 + ], + [ + 288, + 170.667 + ], + [ + 368, + 170.667 + ], + [ + 448, + 170.667 + ] + ] + } + ] + }, + { + "t": 11.25, + "i": {"x": [0.5], "y": [1]}, + "o": {"x": [0.5], "y": [0]}, + "s": [ + { + "c": false, + "i": [[0,0],[0,0],[0,0],[0,0],[0,0]], + "o": [[0,0],[0,0],[0,0],[0,0],[0,0]], + "v": [ + [ + 128, + 170.667 + ], + [ + 208, + 250.667 + ], + [ + 288, + 330.667 + ], + [ + 368, + 250.667 + ], + [ + 448, + 170.667 + ] + ] + } + ] + }, + { + "t": 22.5, + "s": [ + { + "c": false, + "i": [[0,0],[0,0],[0,0],[0,0],[0,0]], + "o": [[0,0],[0,0],[0,0],[0,0],[0,0]], + "v": [ + [ + 128, + 170.667 + ], + [ + 128, + 330.667 + ], + [ + 288, + 330.667 + ], + [ + 288, + 170.667 + ], + [ + 448, + 170.667 + ] + ] + } + ] + } + ], + "a": 1 + } + }, + { + "ty": "st", + "lc": 2, + "lj": 2, + "ml": 0, + "o": { + "k": 100, + "a": 0 + }, + "w": { + "k": [ + { + "t": 0, + "i": {"x": [0.5], "y": [1]}, + "o": {"x": [0.5], "y": [0]}, + "s": [ + 40 + ] + }, + { + "t": 11.25, + "i": {"x": [0.5], "y": [1]}, + "o": {"x": [0.5], "y": [0]}, + "s": [ + 30 + ] + }, + { + "t": 22.5, + "s": [ + 20 + ] + } + ], + "a": 1 + }, + "c": { + "k": [ + 0.196, + 0.314, + 0.69 + ], + "a": 0 + } + }, + { + "ty": "st", + "lc": 2, + "lj": 2, + "ml": 0, + "o": { + "k": 100, + "a": 0 + }, + "w": { + "k": [ + { + "t": 0, + "i": {"x": [0.5], "y": [1]}, + "o": {"x": [0.5], "y": [0]}, + "s": [ + 52 + ] + }, + { + "t": 11.25, + "i": {"x": [0.5], "y": [1]}, + "o": {"x": [0.5], "y": [0]}, + "s": [ + 39 + ] + }, + { + "t": 22.5, + "s": [ + 26 + ] + } + ], + "a": 1 + }, + "c": { + "k": [ + 0.114, + 0.157, + 0.282 + ], + "a": 0 + } + } + ] + } + ] + }, + { + "id": "precomp_1", + "layers": [ + { + "ddd": 0, + "ty": 0, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 0, + "refId": "precomp_0", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 0, + "parent": 101, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 1, + "refId": "precomp_0", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 101 + }, + { + "ddd": 0, + "ty": 0, + "parent": 111, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 2, + "refId": "precomp_0", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "p": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "r": { + "k": 180, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 111 + }, + { + "ddd": 0, + "ty": 0, + "parent": 121, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 3, + "refId": "precomp_0", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 121 + } + ] + }, + { + "id": "precomp_2", + "layers": [ + { + "ddd": 0, + "ty": 0, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 0, + "refId": "precomp_1", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 0, + "parent": 102, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 1, + "refId": "precomp_1", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 102 + }, + { + "ddd": 0, + "ty": 0, + "parent": 112, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 2, + "refId": "precomp_1", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "p": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 180, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 112 + }, + { + "ddd": 0, + "ty": 0, + "parent": 122, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 3, + "refId": "precomp_1", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 122 + } + ] + }, + { + "id": "precomp_3", + "layers": [ + { + "ddd": 0, + "ty": 0, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 0, + "refId": "precomp_2", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 0, + "parent": 103, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 1, + "refId": "precomp_2", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 103 + }, + { + "ddd": 0, + "ty": 0, + "parent": 113, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 2, + "refId": "precomp_2", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "p": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 180, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 113 + }, + { + "ddd": 0, + "ty": 0, + "parent": 123, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 3, + "refId": "precomp_2", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 123 + } + ] + }, + { + "id": "precomp_4", + "layers": [ + { + "ddd": 0, + "ty": 0, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 0, + "refId": "precomp_3", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 0, + "parent": 104, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 1, + "refId": "precomp_3", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 104 + }, + { + "ddd": 0, + "ty": 0, + "parent": 114, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 2, + "refId": "precomp_3", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "p": { + "k": [ + 208, + 250.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 180, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 114 + }, + { + "ddd": 0, + "ty": 0, + "parent": 124, + "sr": 1, + "ks": { + "a": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "p": { + "k": [ + 128, + 170.667 + ], + "a": 0 + }, + "s": { + "k": [ + 50, + 50 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 22.5, + "bm": 0, + "ind": 3, + "refId": "precomp_3", + "w": 512, + "h": 512 + }, + { + "ddd": 0, + "ty": 3, + "sr": 1, + "ks": { + "a": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "p": { + "k": [ + 288, + 330.667 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 90, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 124 + } + ] + } + ], + "layers": [ + { + "ty": 0, + "ks": {}, + "ip": 0, + "op": 22.5, + "st": 0, + "refId": "precomp_0", + "w": 512, + "h": 512 + }, + { + "ty": 0, + "ks": {}, + "ip": 0, + "op": 45, + "st": 0, + "refId": "precomp_1", + "w": 512, + "h": 512 + }, + { + "ty": 0, + "ks": {}, + "ip": 0, + "op": 67.5, + "st": 0, + "refId": "precomp_2", + "w": 512, + "h": 512 + }, + { + "ty": 0, + "sr": 1, + "ks": {}, + "ip": 0, + "op": 100, + "st": 0, + "refId": "precomp_3", + "w": 512, + "h": 512 + } + ] +} diff --git a/examples/gradient.json b/examples/gradient.json new file mode 100644 index 00000000..043b3be6 --- /dev/null +++ b/examples/gradient.json @@ -0,0 +1,1255 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{3da63a46-0ec5-45b8-90fb-d31c5614d5be}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 1, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer 2", + "mn": "{04a8ef87-75fd-451c-868b-7413969c8ad9}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "e", + "mn": "{078a0bf7-08ce-49f7-9dca-c473ad9ff09d}", + "it": [ + { + "ty": "gr", + "nm": "e", + "mn": "{efb1ff36-fe2b-4939-97a5-d75a167d003b}", + "it": [ + { + "ty": "gr", + "nm": "e", + "mn": "{759da60a-0439-496c-89a9-66e1d721ceb7}", + "it": [ + { + "ty": "gr", + "nm": "", + "mn": "{b56ba91b-5ef9-40d2-a1da-27265d105c7a}", + "it": [ + { + "ty": "sh", + "nm": "", + "mn": "{020e377d-646e-45f6-830f-756cfff57aa9}", + "ks": { + "a": 0, + "k": { + "c": true, + "v": [ + [ + 3.7994567051676293, + -7.097994637365934 + ], + [ + 5.33994951436286, + -6.707992504500113 + ], + [ + 6.327946284594615, + -5.609490432573314 + ], + [ + 6.672442201680043, + -3.952002315682892 + ], + [ + 6.672442201680043, + -3.262995246756169 + ], + [ + 1.901449879997, + -3.262995246756169 + ], + [ + 2.505949758118953, + -1.4624984765244131 + ], + [ + 4.124444517362934, + -0.8449957342683567 + ], + [ + 5.300948539338484, + -0.968496282719568 + ], + [ + 6.360449636240906, + -1.326002681317033 + ], + [ + 6.360449636240906, + -0.32500304695117377 + ], + [ + 5.307446162716568, + 0.019500487512187806 + ], + [ + 4.072448295582389, + 0.12999817182929574 + ], + [ + 2.3239477471311782, + -0.2729992077926948 + ], + [ + 1.1409537191554788, + -1.4755013406585165 + ], + [ + 0.7184558520213006, + -3.4319943936098403 + ], + [ + 1.1019527441311032, + -5.395000304695118 + ], + [ + 2.1809543285457136, + -6.655996282719569 + ], + [ + 3.7994567051676293, + -7.097994637365934 + ] + ], + "i": [ + [ + 0, + 0 + ], + [ + -0.4290005687642191, + -0.2600014219105473 + ], + [ + -0.22966394472361795, + -0.4723332927073187 + ], + [ + 0, + -0.6326587852196304 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.3856627665691641, + -0.411668494837371 + ], + [ + -0.69333373959349, + 0 + ], + [ + -0.34233512087802254, + 0.08233369896747422 + ], + [ + -0.3639989437235931, + 0.15600390009750242 + ], + [ + 0, + 0 + ], + [ + 0.34666686979674477, + -0.07366512287807196 + ], + [ + 0.47666504162604095, + 0 + ], + [ + 0.506997440561014, + 0.2686649197479937 + ], + [ + 0.281665244756119, + 0.5330031688292207 + ], + [ + 0, + 0.7713255331383286 + ], + [ + -0.25566459473986836, + 0.5459984155853892 + ], + [ + -0.4636697948698716, + 0.29466556976424485 + ], + [ + -0.6153317895447388, + 0 + ] + ], + "o": [ + [ + 0.5979946373659342, + 0 + ], + [ + 0.4290005687642182, + 0.2600014219105473 + ], + [ + 0.22966394472361795, + 0.47233329270731783 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.017337152178804383, + 0.7886626853171328 + ], + [ + 0.3856627665691641, + 0.411668494837371 + ], + [ + 0.4420008937723443, + 0 + ], + [ + 0.34233512087802165, + -0.08233369896747411 + ], + [ + 0, + 0 + ], + [ + -0.35533544588614685, + 0.15600390009750242 + ], + [ + -0.34666686979674477, + 0.07366512287807195 + ], + [ + -0.6586695917397929, + 0 + ], + [ + -0.5069974405610138, + -0.26866491974799367 + ], + [ + -0.28166524475611887, + -0.5330031688292207 + ], + [ + 0, + -0.7626721918047954 + ], + [ + 0.2556645947398686, + -0.5459984155853901 + ], + [ + 0.46366979486987203, + -0.29466556976424396 + ], + [ + 0, + 0 + ] + ] + } + } + }, + { + "ty": "sh", + "nm": "", + "mn": "{b3f5759c-30aa-4352-a4ea-23b71ead28ad}", + "ks": { + "a": 0, + "k": { + "c": false, + "v": [ + [ + 3.7864462236555916, + -6.162001706292657 + ], + [ + 2.4929545113627842, + -5.635496160841521 + ], + [ + 1.9274556082652068, + -4.172997684317108 + ], + [ + 5.476452926948174, + -4.172997684317108 + ], + [ + 5.06045268319208, + -5.609498049951249 + ], + [ + 3.7864462236555916, + -6.162001706292657 + ] + ], + "i": [ + [ + 0, + 0 + ], + [ + 0.3163344708617717, + -0.3510036969674246 + ], + [ + 0.06066479786994661, + -0.6239952873821846 + ], + [ + 0, + 0 + ], + [ + 0.2686699979999494, + 0.36833577089427205 + ], + [ + 0.5806676416910426, + 0 + ] + ], + "o": [ + [ + -0.5459933373334334, + 0 + ], + [ + -0.3163344708617717, + 0.3510036969674246 + ], + [ + 0, + 0 + ], + [ + -0.008663497837446243, + -0.5893311395284879 + ], + [ + -0.2686699979999503, + -0.36833577089427205 + ], + [ + 0, + 0 + ] + ] + } + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "fl", + "nm": "Fill 1", + "mn": "{2fcb588a-7de7-4cba-8508-46952f160940}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -2.7166567164177735, + 3.822454790113566 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 16 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "gr", + "nm": "s", + "mn": "{e16b0057-203a-4dab-8e5b-495775987f85}", + "it": [ + { + "ty": "gr", + "nm": "s", + "mn": "{07bcfe04-40c2-4636-807c-d64982f7a44d}", + "it": [ + { + "ty": "gr", + "nm": "s", + "mn": "{0de90988-3e53-4e7a-8a7d-cb147d0c42b5}", + "it": [ + { + "ty": "sh", + "nm": "", + "mn": "{22460e65-f67b-48b8-844b-e361867d003b}", + "ks": { + "a": 0, + "k": { + "c": false, + "v": [ + [ + 5.645452073801845, + -1.923997318682967 + ], + [ + 4.891453536338409, + -0.39000213286582164 + ], + [ + 2.8634485393384836, + 0.12999817182929574 + ], + [ + 1.608957802070052, + 0.013002864134103353 + ], + [ + 0.679454876996925, + -0.311992565439136 + ], + [ + 0.679454876996925, + -1.3519931748293708 + ], + [ + 1.6869521347408687, + -0.968496282719568 + ], + [ + 2.8894542676066903, + -0.7929995124878122 + ], + [ + 4.150450245631141, + -1.0724963436585915 + ], + [ + 4.540444761119028, + -1.820004875121878 + ], + [ + 4.3974513425335635, + -2.2880013406585165 + ], + [ + 3.8839562785944652, + -2.7040015844146104 + ], + [ + 2.824447564314108, + -3.171998049951249 + ], + [ + 1.6674516472286809, + -3.6919983546463664 + ], + [ + 0.9264559738993475, + -4.315998720280507 + ], + [ + 0.666459630240756, + -5.251999268731718 + ], + [ + 1.3879548160579016, + -6.616995307695193 + ], + [ + 3.2794487830945775, + -7.097994637365934 + ], + [ + 4.468948051826296, + -6.9744940889147236 + ], + [ + 5.502443420460512, + -6.629998171829296 + ], + [ + 5.1124489049726245, + -5.719995734268357 + ], + [ + 4.189443603277582, + -6.031995917085427 + ], + [ + 3.2014468330458263, + -6.162001706292657 + ], + [ + 2.128950489387235, + -5.934501096902423 + ], + [ + 1.7584564614115354, + -5.316990737268432 + ], + [ + 1.9274556082652068, + -4.82950140159754 + ], + [ + 2.4929545113627842, + -4.439499268731718 + ], + [ + 3.552455608265207, + -3.9910032907072677 + ], + [ + 4.683453414460362, + -3.4839982327683194 + ], + [ + 5.398450976899423, + -2.853500243756094 + ], + [ + 5.645452073801845, + -1.923997318682967 + ] + ], + "i": [ + [ + 0, + 0 + ], + [ + 0.5026656916422914, + -0.346666869796745 + ], + [ + 0.8493376396909924, + 0 + ], + [ + 0.35099861871546767, + 0.07799687179679493 + ], + [ + 0.26866999799995006, + 0.13866674791869799 + ], + [ + 0, + 0 + ], + [ + -0.3943313426585666, + -0.11699784682117054 + ], + [ + -0.4073367459186481, + 0 + ], + [ + -0.2599963436585919, + 0.18633122078051945 + ], + [ + 0, + 0.31200780019500485 + ], + [ + 0.09532894572364281, + 0.13866674791869782 + ], + [ + 0.2470010969024221, + 0.13866674791869782 + ], + [ + 0.45933804595114847, + 0.17333089577239447 + ], + [ + 0.32066621978049437, + 0.17333597402435075 + ], + [ + 0.17333089577239413, + 0.24266426973174227 + ], + [ + 0, + 0.38133609590239725 + ], + [ + -0.48099679054476374, + 0.32066621978049437 + ], + [ + -0.779999187479687, + 0 + ], + [ + -0.36833577089427294, + -0.08233369896747345 + ], + [ + -0.32066114152853853, + -0.14733024575614362 + ], + [ + 0, + 0 + ], + [ + 0.32066621978049437, + 0.08667052613815329 + ], + [ + 0.3379982937073427, + 0 + ], + [ + 0.24699601865046583, + -0.15166707292682258 + ], + [ + 0, + -0.2600065001625049 + ], + [ + -0.11266609790244764, + -0.13433499899997603 + ], + [ + -0.26433317082927044, + -0.12566642291057306 + ], + [ + -0.4420008937723443, + -0.17333089577239447 + ], + [ + -0.3119976436910923, + -0.1733359740243503 + ], + [ + -0.16466739793494867, + -0.24699601865046628 + ], + [ + 0, + -0.3726725980649519 + ] + ], + "o": [ + [ + 0, + 0.6759965874146854 + ], + [ + -0.5026656916422914, + 0.3466668697967449 + ], + [ + -0.4853285394634863, + 0 + ], + [ + -0.3509986187154679, + -0.07799687179679493 + ], + [ + 0, + 0 + ], + [ + 0.27733349583739597, + 0.13866674791869804 + ], + [ + 0.3943313426585664, + 0.11699784682117043 + ], + [ + 0.5806676416910421, + 0 + ], + [ + 0.2599963436585915, + -0.18633122078051967 + ], + [ + 0, + -0.17333089577239424 + ], + [ + -0.09532894572364281, + -0.13866674791869826 + ], + [ + -0.24700109690242256, + -0.13866674791869826 + ], + [ + -0.45066439160979055, + -0.17333089577239447 + ], + [ + -0.3206662197804946, + -0.1733359740243503 + ], + [ + -0.17333089577239436, + -0.24266426973174315 + ], + [ + 0, + -0.5893311395284879 + ], + [ + 0.4809967905447634, + -0.3206662197804935 + ], + [ + 0.4246637415935397, + 0 + ], + [ + 0.36833577089427205, + 0.08233369896747433 + ], + [ + 0, + 0 + ], + [ + -0.2946706480162007, + -0.12132959573989321 + ], + [ + -0.3206662197804948, + -0.08667052613815329 + ], + [ + -0.4680015437885947, + 0 + ], + [ + -0.2469960186504665, + 0.15166707292682347 + ], + [ + 0, + 0.1906578914472865 + ], + [ + 0.11266609790244786, + 0.13433499899997514 + ], + [ + 0.26433317082927044, + 0.12566642291057306 + ], + [ + 0.44200089377234475, + 0.16466739793494822 + ], + [ + 0.3119976436910914, + 0.17333597402435075 + ], + [ + 0.16466739793494867, + 0.24699601865046583 + ], + [ + 0, + 0 + ] + ] + } + } + }, + { + "ty": "fl", + "nm": "Fill 1", + "mn": "{2fcb588a-7de7-4cba-8508-46952f160940}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + -2.7166567164177735, + 3.822454790113566 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 496 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{a5276bb6-4d7c-4b4f-b371-a0e14a279176}", + "ks": { + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Gradient", + "mn": "{9df3ba96-24a3-412e-abd4-e64e2e76e6df}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{20934ad0-1c22-4752-a5b1-be99889ea79a}", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 512, + 512 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "gf", + "nm": "Gradient Fill", + "o": { + "a": 0, + "k": 100 + }, + "r": 1, + "s": { + "a": 0, + "k": [ + 256, + 496 + ] + }, + "e": { + "a": 0, + "k": [ + 256, + 16 + ] + }, + "t": 1, + "h": { + "a": 0, + "k": 0 + }, + "a": { + "a": 0, + "k": 0 + }, + "g": { + "p": 3, + "k": { + "a": 0, + "k": [ + 0, + 0.7686274509803922, + 0.8509803921568627, + 0.9607843137254902, + 0.5, + 0.19600213626306554, + 0.31400015259021896, + 0.6899977111467155, + 1, + 0.16099794003204396, + 0.18399328603036547, + 0.45900663767452504, + 0, + 1, + 0.5, + 1, + 1, + 1 + ] + } + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 257.4805970149254, + 255.76119402985074 + ] + }, + "p": { + "a": 0, + "k": [ + 257.4805970149254, + 255.76119402985074 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/image.json b/examples/image.json new file mode 100644 index 00000000..9f6b7699 --- /dev/null +++ b/examples/image.json @@ -0,0 +1,74 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + } + ], + "layers": [ + { + "nm": "foo", + "mn": "bar", + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "a": { + "k": [ + 256, + 256 + ], + "a": 0 + }, + "p": { + "k": [ + 256, + 256 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 60, + "st": 0, + "bm": 0, + "ind": 0, + "refId": "blep" + } + ] +} diff --git a/examples/image_animated.json b/examples/image_animated.json new file mode 100644 index 00000000..a23d8859 --- /dev/null +++ b/examples/image_animated.json @@ -0,0 +1,94 @@ +{ + "v": "5.5.2", + "nm": "Animation", + "fr": 60, + "ip": 0, + "op": 180, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [ + { + "id": "blep", + "h": 512, + "w": 512, + "p": "/lottie-docs/examples/blep.png", + "u": "", + "e": 1 + }, + { + "id": "precomp0", + "nm": "Precomp", + "layers": [] + } + ], + "layers": [ + { + "nm": "Layer", + "ddd": 0, + "ty": 2, + "sr": 1, + "ks": { + "nm": "Transform", + "a": { + "k": [ + 256, + 256 + ], + "a": 0 + }, + "p": { + "k": [ + 256, + 256 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "nm": "Rotation", + "ix": 123, + "a": 1, + "k": [ + { + "t": 0, + "s": [0], + "i": {"x": [1], "y": [1]}, + "o": {"x": [1], "y": [1]} + }, + { + "t": 180, + "s": [360] + } + ] + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 180, + "st": 0, + "bm": 0, + "ind": 0, + "refId": "blep" + } + ] +} + diff --git a/examples/layer_order.json b/examples/layer_order.json new file mode 100644 index 00000000..951de169 --- /dev/null +++ b/examples/layer_order.json @@ -0,0 +1,309 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{7c55df9e-4c06-4afe-bcb7-a2b4b9d5f7c9}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 1, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Ellipse", + "mn": "{0a36d01c-18e1-48d3-8e8f-cc093b3f24ba}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Ellipse", + "mn": "{f1becc2a-49f0-4f0c-918f-bdffe4c6870f}", + "it": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{2aabac6e-1dd8-41b0-b60b-baf75ccb6318}", + "p": { + "a": 0, + "k": [ + 303.9044776119403, + 324.9671641791045 + ] + }, + "s": { + "a": 0, + "k": [ + 205.46865671641788, + 204.6089552238806 + ] + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{be0ec062-125f-46e3-bb2b-c9abfd75d49f}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{b1921647-2329-42c2-af2d-5379557b5b54}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 303.9044776119403, + 324.9671641791045 + ] + }, + "p": { + "a": 0, + "k": [ + 330.55522388059705, + 308.63283582089554 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Rectangle", + "mn": "{50b511ea-ca42-416e-b630-58eca8fb41d9}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Rectangle", + "mn": "{c338119b-6435-437a-a855-0f36a8264c22}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{9e7f37be-ac4b-411e-8e47-3e2a2cad9102}", + "p": { + "a": 0, + "k": [ + 185.69552238805971, + 256.1910447761194 + ] + }, + "s": { + "a": 0, + "k": [ + 268.2268656716418, + 225.24179104477614 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{9781440d-fa0d-45e1-b224-8c96fefc1f09}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{dc302cc0-3912-40b0-81da-03b5c172432c}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 185.69552238805971, + 256.1910447761194 + ] + }, + "p": { + "a": 0, + "k": [ + 212.34626865671646, + 239.85671641791043 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/layers-solid.json b/examples/layers-solid.json new file mode 100644 index 00000000..cc5e5640 --- /dev/null +++ b/examples/layers-solid.json @@ -0,0 +1,20 @@ +{ + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ddd": 0, + "layers": [ + { + "ty": 1, + "ip": 0, + "op": 60, + "st": 0, + "ks": {}, + "sc": "#ff0000", + "sh": 512, + "sw": 512 + } + ] +} diff --git a/examples/mask.json b/examples/mask.json new file mode 100644 index 00000000..c98092bc --- /dev/null +++ b/examples/mask.json @@ -0,0 +1,315 @@ +{ + "v": "5.5.7", + "ip": 0, + "op": 180, + "nm": "Animation", + "mn": "{b3d1b083-9de7-4537-a691-fc9aa42f9742}", + "fr": 60, + "w": 512, + "h": 512, + "assets": [], + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 2, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Shapes", + "ks": {}, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{528994b7-40ff-4d12-81f8-603f274da12e}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{ce8756d7-289f-4f84-a135-d225d57c42e0}", + "p": { + "a": 0, + "k": [ + 427.2716417910448, + 194.29253731343283 + ] + }, + "or": { + "a": 0, + "k": 216.4160919189453 + }, + "ir": { + "a": 0, + "k": 87.03440856933594 + }, + "r": { + "a": 0, + "k": 261.54803466796875 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{efd05a25-a43b-451d-83d2-53a477087223}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{523ca39c-9e57-4547-bf0e-ba7496003579}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 427.2716417910448, + 194.29253731343283 + ] + }, + "p": { + "a": 0, + "k": [ + 338.7223880597015, + 209.76716417910447 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "gr", + "nm": "Rectangle", + "mn": "{d2d7a5d5-6d91-42e8-b40a-af52a112fe38}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{9ef8604e-7891-4909-a655-445131b4d842}", + "p": { + "a": 0, + "k": [ + 209.17611940298502, + 226.8 + ] + }, + "s": { + "a": 0, + "k": [ + 363.3313432835821, + 369.3492537313433 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{444584d2-cb59-4cba-83a1-82cc605837fd}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{f75aed67-9b0e-41a9-b859-a14b5b0a320d}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.7686274509803922, + 0.8509803921568627, + 0.9607843137254902 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 256.1910447761194, + 273.8149253731343 + ] + }, + "p": { + "a": 0, + "k": [ + 256.1910447761194, + 273.8149253731343 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ], + "hasMask": true, + "masksProperties": [ + { + "mode": "a", + "o": { + "a": 0, + "k": 100 + }, + "inv": false, + "x": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": { + "c": true, + "v": [ + [ + 247.109, + 125.719 + ], + [ + 66.109, + 306.719 + ], + [ + 424.109, + 389.719 + ] + ], + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ] + } + } + } + ] + } + ], + "meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" + } +} diff --git a/examples/matte.json b/examples/matte.json new file mode 100644 index 00000000..7c55b28b --- /dev/null +++ b/examples/matte.json @@ -0,0 +1,389 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{b3d1b083-9de7-4537-a691-fc9aa42f9742}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 1, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Ellipse (Mask)", + "ks": { + "a": { + "a": 0, + "k": [ + 153, + 294 + ] + }, + "p": { + "a": 0, + "k": [ + 346, + 211 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{261eddeb-af92-4be1-932c-790b00c23933}", + "p": { + "a": 0, + "k": [ + 137.0955223880597, + 293.60820895522386 + ] + }, + "s": { + "a": 0, + "k": [ + 303.42089552238804, + 315.55074626865667 + ] + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{aa9c282c-253d-4d8d-ab05-4819c592fa85}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 1, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 6 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{2b2b0002-ff0c-4978-a33b-db4e0498848d}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ] + }, + "r": 1 + } + ], + "td": 1 + }, + { + "ddd": 0, + "ty": 4, + "ind": 2, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Shapes (Masked)", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{528994b7-40ff-4d12-81f8-603f274da12e}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{ce8756d7-289f-4f84-a135-d225d57c42e0}", + "p": { + "a": 0, + "k": [ + 427.2716417910448, + 194.29253731343283 + ] + }, + "or": { + "a": 0, + "k": 216.4160919189453 + }, + "ir": { + "a": 0, + "k": 87.03440856933594 + }, + "r": { + "a": 0, + "k": 261.54803466796875 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{efd05a25-a43b-451d-83d2-53a477087223}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{523ca39c-9e57-4547-bf0e-ba7496003579}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 427.2716417910448, + 194.29253731343283 + ] + }, + "p": { + "a": 0, + "k": [ + 338.7223880597015, + 209.76716417910447 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + }, + { + "ty": "gr", + "nm": "Rectangle", + "mn": "{d2d7a5d5-6d91-42e8-b40a-af52a112fe38}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{9ef8604e-7891-4909-a655-445131b4d842}", + "p": { + "a": 0, + "k": [ + 209.17611940298502, + 226.8 + ] + }, + "s": { + "a": 0, + "k": [ + 363.3313432835821, + 369.3492537313433 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{444584d2-cb59-4cba-83a1-82cc605837fd}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{f75aed67-9b0e-41a9-b859-a14b5b0a320d}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.7686274509803922, + 0.8509803921568627, + 0.9607843137254902 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 256.1910447761194, + 273.8149253731343 + ] + }, + "p": { + "a": 0, + "k": [ + 256.1910447761194, + 273.8149253731343 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ], + "tt": 1, + "tp": 1 + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/offset-path.json b/examples/offset-path.json new file mode 100644 index 00000000..e8d00299 --- /dev/null +++ b/examples/offset-path.json @@ -0,0 +1,176 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{9199543e-3552-4e51-a802-623f2a4a2ca1}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{57cff206-c227-4a14-a679-195157be886b}", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "or": { + "a": 0, + "k": 222.72242736816406 + }, + "ir": { + "a": 0, + "k": 111.36121368408203 + }, + "r": { + "a": 0, + "k": 358.67291259765625 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "op", + "nm": "Offset Path", + "mn": "{b4af429a-546e-4728-a869-711a404c55ae}", + "a": { + "a": 0, + "k": 10 + }, + "lj": 2, + "ml": { + "a": 0, + "k": 100 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 3 + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} + + diff --git a/examples/parenting.json b/examples/parenting.json new file mode 100644 index 00000000..b1ad771d --- /dev/null +++ b/examples/parenting.json @@ -0,0 +1,575 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{5a5e02ed-29e6-48bd-9a1b-8abab56b291a}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 3, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Parent", + "mn": "{6b75ee6c-2ceb-4ad5-9ce5-a7699d15d77d}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 182.92537313432845, + 259.43880597014925 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 354.0059701492536, + 256.8597014925372 + ] + }, + { + "t": 90, + "s": [ + 354.0059701492536, + 256.8597014925372 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + }, + "e": [ + 182.92537313432845, + 259.43880597014925 + ] + }, + { + "t": 180, + "s": [ + 182.92537313432845, + 259.43880597014925 + ] + } + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + }, + { + "ddd": 0, + "ty": 4, + "ind": 3, + "st": 0, + "ip": 0, + "op": 180, + "nm": "PolyStar", + "mn": "{a4879a0a-0321-4a6e-b73d-d79fb54c6cf6}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "parent": 0, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{66c0b9ae-c631-4729-bf92-62bd5d0579de}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{28f044f6-2360-4f0c-8a74-1970156e8d51}", + "p": { + "a": 0, + "k": [ + 192.5731343283582, + 324.9671641791045 + ] + }, + "or": { + "a": 0, + "k": 125.17442321777344 + }, + "ir": { + "a": 0, + "k": 62.58721160888672 + }, + "r": { + "a": 0, + "k": 142.81529235839844 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{8c9d7c3c-ebfe-41da-a473-7ae85339009d}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{a2487e80-9cef-4583-83d0-2fcb5f25dc08}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 192.5731343283582, + 324.9671641791045 + ] + }, + "p": { + "a": 0, + "k": [ + 192.5731343283582, + 324.9671641791045 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 2, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Rectangle", + "mn": "{8d3f400e-a0cb-47a8-ae8e-047fa459618d}", + "ks": { + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Rectangle", + "mn": "{daaed6c7-5607-4610-91f7-832728952509}", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{fe0a26f5-7618-4874-8c37-b1b63dc1b1ff}", + "p": { + "a": 0, + "k": [ + 252.75223880597017, + 277.25373134328356 + ] + }, + "s": { + "a": 0, + "k": [ + 438.44776119402985, + 167.6417910447761 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{2bbf3c23-e0ab-4eb1-a70b-bc42c055922d}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{0b14d755-d996-4024-bc07-c64c20b23093}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 252.75223880597017, + 277.25373134328356 + ] + }, + "p": { + "a": 0, + "k": [ + 252.75223880597017, + 277.25373134328356 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 1, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Ellipse", + "mn": "{6a785c9e-8426-4476-80c1-c48669dc41a9}", + "ks": { + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "parent": 0, + "shapes": [ + { + "ty": "gr", + "nm": "Ellipse", + "mn": "{ee3b4044-d70a-4afa-8312-691235c2ad19}", + "it": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{4c3c94e1-6f79-4422-8561-9f76ac252047}", + "p": { + "a": 0, + "k": [ + 323.24776119402986, + 177.95820895522388 + ] + }, + "s": { + "a": 0, + "k": [ + 182.25671641791044, + 182.2567164179104 + ] + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{7b8fc06a-febf-4684-9a00-abe79e4eed86}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{94dd9683-42c3-4542-a8d1-983f21fdfb6e}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 323.24776119402986, + 177.95820895522388 + ] + }, + "p": { + "a": 0, + "k": [ + 323.24776119402986, + 177.95820895522388 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/precomp/circle.json b/examples/precomp/circle.json new file mode 100644 index 00000000..d1b28a50 --- /dev/null +++ b/examples/precomp/circle.json @@ -0,0 +1,204 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 60, +"nm": "Animation", +"mn": "{f34e95a3-8930-4f41-a339-95fff6da1b13}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "nm": "Layer", + "mn": "{456fdfe5-686b-4006-92f4-951c47ab4bc7}", + "ks": {}, + "shapes": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{05d5f1a0-6046-4aea-a405-b9ba60a24bd7}", + "d": 1, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0, + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 730, + 730 + ] + } + ] + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{d835adb4-6502-4e3e-98c2-70d1145f1a23}", + "o": { + "a": 0, + "k": 100 + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 6 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "c": { + "a": 0, + "k": [ + 0.11372549019607843, + 0.1568627450980392, + 0.2823529411764706 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{78036603-40f1-42ca-ada5-fee506b4ac58}", + "o": { + "a": 1, + "k": [ + { + "t": 30, + "s": [ + 100 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "r": 1, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + } + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.5.0-93-g187709f5" +} +} diff --git a/examples/precomp/star-circle.json b/examples/precomp/star-circle.json new file mode 100644 index 00000000..e6466bdb --- /dev/null +++ b/examples/precomp/star-circle.json @@ -0,0 +1,632 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 60, +"nm": "Animation", +"mn": "{0b14b755-3d9e-4f7f-b7ab-21cd57d13e23}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ + { + "id": "Star", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "nm": "Shape Layer", + "mn": "{4d57cabf-951f-4067-b50e-8307f9f5fe72}", + "ks": {}, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{c99b4a89-363b-4cd3-8797-bf65b57fdd29}", + "d": 1, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 256, + 256 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0, + 0 + ] + } + ] + }, + "or": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "ir": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "is": { + "a": 0, + "k": 0 + }, + "os": { + "a": 0, + "k": 0 + }, + "r": { + "a": 0, + "k": -45 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1 + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{eb7fbdff-0656-41f5-9337-3aa283dde263}", + "o": { + "a": 0, + "k": 100 + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 6 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.3411764705882353, + 0.01568627450980392 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{54bfe210-7450-4824-accc-eef8f6c48ae8}", + "o": { + "a": 0, + "k": 100 + }, + "r": 1, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + } + } + ] + } + ] + }, + { + "id": "Expanding Stars", + "layers": [ + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 0} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 45} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 90} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 135} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 180} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": -45} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": -90} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": -135} + } + } + ] + }, + { + "id": "Circle", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "nm": "Layer", + "mn": "{456fdfe5-686b-4006-92f4-951c47ab4bc7}", + "ks": {}, + "shapes": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{05d5f1a0-6046-4aea-a405-b9ba60a24bd7}", + "d": 1, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0, + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 730, + 730 + ] + } + ] + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{d835adb4-6502-4e3e-98c2-70d1145f1a23}", + "o": { + "a": 0, + "k": 100 + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 6 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "c": { + "a": 0, + "k": [ + 0.11372549019607843, + 0.1568627450980392, + 0.2823529411764706 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{78036603-40f1-42ca-ada5-fee506b4ac58}", + "o": { + "a": 1, + "k": [ + { + "t": 30, + "s": [ + 100 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "r": 1, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + } + } + ] + } + ] + } +], +"layers": [ + { + "nm": "Expanding Stars Layer", + "refId": "Expanding Stars", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": {} + }, + { + "nm": "Circle Layer", + "refId": "Circle", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": {} + } +] +} diff --git a/examples/precomp/star-comp.json b/examples/precomp/star-comp.json new file mode 100644 index 00000000..fec56ac4 --- /dev/null +++ b/examples/precomp/star-comp.json @@ -0,0 +1,310 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 60, +"nm": "Animation", +"mn": "{0b14b755-3d9e-4f7f-b7ab-21cd57d13e23}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ + { + "id": "Star", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "nm": "Shape Layer", + "mn": "{4d57cabf-951f-4067-b50e-8307f9f5fe72}", + "ks": {}, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{c99b4a89-363b-4cd3-8797-bf65b57fdd29}", + "d": 1, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 256, + 256 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0, + 0 + ] + } + ] + }, + "or": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "ir": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "is": { + "a": 0, + "k": 0 + }, + "os": { + "a": 0, + "k": 0 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1 + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{eb7fbdff-0656-41f5-9337-3aa283dde263}", + "o": { + "a": 0, + "k": 100 + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 6 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.3411764705882353, + 0.01568627450980392 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{54bfe210-7450-4824-accc-eef8f6c48ae8}", + "o": { + "a": 0, + "k": 100 + }, + "r": 1, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + } + } + ] + } + ] + } +], +"layers": [ + { + "ddd": 0, + "ty": 0, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "nm": "Precomp Layer", + "ks": {}, + "refId": "Star" + } +], +"meta": { + "g": "Glaxnimate 0.5.0-93-g187709f5" +} +} + diff --git a/examples/precomp/star-nocomp.json b/examples/precomp/star-nocomp.json new file mode 100644 index 00000000..b7742bbc --- /dev/null +++ b/examples/precomp/star-nocomp.json @@ -0,0 +1,291 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 60, +"nm": "Animation", +"mn": "{0b14b755-3d9e-4f7f-b7ab-21cd57d13e23}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "nm": "Shape Layer", + "mn": "{4d57cabf-951f-4067-b50e-8307f9f5fe72}", + "ks": {}, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{c99b4a89-363b-4cd3-8797-bf65b57fdd29}", + "d": 1, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 256, + 256 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0, + 0 + ] + } + ] + }, + "or": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "ir": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "is": { + "a": 0, + "k": 0 + }, + "os": { + "a": 0, + "k": 0 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1 + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{eb7fbdff-0656-41f5-9337-3aa283dde263}", + "o": { + "a": 0, + "k": 100 + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 6 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.3411764705882353, + 0.01568627450980392 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{54bfe210-7450-4824-accc-eef8f6c48ae8}", + "o": { + "a": 0, + "k": 100 + }, + "r": 1, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + } + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.5.0-93-g187709f5" +} +} diff --git a/examples/precomp/star-splosion.json b/examples/precomp/star-splosion.json new file mode 100644 index 00000000..79722778 --- /dev/null +++ b/examples/precomp/star-splosion.json @@ -0,0 +1,418 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 60, +"nm": "Animation", +"mn": "{0b14b755-3d9e-4f7f-b7ab-21cd57d13e23}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ + { + "id": "Star", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 60, + "nm": "Shape Layer", + "mn": "{4d57cabf-951f-4067-b50e-8307f9f5fe72}", + "ks": {}, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{c99b4a89-363b-4cd3-8797-bf65b57fdd29}", + "d": 1, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 256, + 256 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0, + 0 + ] + } + ] + }, + "or": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 80 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "ir": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 0 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 30, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 51, + "s": [ + 40 + ], + "h": 0, + "o": { + "x": [ + 0 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 1 + ], + "y": [ + 1 + ] + } + }, + { + "t": 60, + "s": [ + 0 + ] + } + ] + }, + "is": { + "a": 0, + "k": 0 + }, + "os": { + "a": 0, + "k": 0 + }, + "r": { + "a": 0, + "k": -45 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1 + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{eb7fbdff-0656-41f5-9337-3aa283dde263}", + "o": { + "a": 0, + "k": 100 + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 6 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.3411764705882353, + 0.01568627450980392 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{54bfe210-7450-4824-accc-eef8f6c48ae8}", + "o": { + "a": 0, + "k": 100 + }, + "r": 1, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + } + } + ] + } + ] + } +], +"layers": [ + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 0} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 45} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 90} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 135} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": 180} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": -45} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": -90} + } + }, + { + "nm": "Precomp Layer", + "refId": "Star", + "ty": 0, + "st": 0, + "ip": 0, + "op": 60, + "w": 512, + "h": 512, + "ks": { + "a": {"a": 0, "k": [256, 256]}, + "p": {"a": 0, "k": [256, 256]}, + "r": {"a": 0, "k": -135} + } + } +], +"meta": { + "g": "Glaxnimate 0.5.0-93-g187709f5" +} +} + + diff --git a/examples/pucker_bloat.json b/examples/pucker_bloat.json new file mode 100644 index 00000000..be98221c --- /dev/null +++ b/examples/pucker_bloat.json @@ -0,0 +1,180 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{9199543e-3552-4e51-a802-623f2a4a2ca1}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{57cff206-c227-4a14-a679-195157be886b}", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "or": { + "a": 0, + "k": 160 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 2, + "os": { + "a": 0, + "k": 0 + } + }, + { + "ty": "pb", + "nm": "Inflate and Deflate", + "mn": "{b4af429a-546e-4728-a869-711a404c55ae}", + "a": { + "a": 0, + "k": 50 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "hd": true, + "nm": "Fill", + "mn": "{a1bcc159-6916-4718-841d-a99140c0e74b}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/rectangle.json b/examples/rectangle.json new file mode 100644 index 00000000..5fd0e66c --- /dev/null +++ b/examples/rectangle.json @@ -0,0 +1,145 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "Group", + "it": [ + { + "ty": "rc", + "nm": "Rectangle", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} + diff --git a/examples/remapping.json b/examples/remapping.json new file mode 100644 index 00000000..f629fa80 --- /dev/null +++ b/examples/remapping.json @@ -0,0 +1,338 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{7820523d-dd32-453b-b311-50323a49e4df}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ + { + "nm": "Composition", + "mn": "{4d838004-a221-48cb-966f-399347c5acb8}", + "id": "{4d838004-a221-48cb-966f-399347c5acb8}", + "layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer 1", + "mn": "{8afc4794-97eb-4533-814b-f92676e324f5}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar 1", + "mn": "{600eb536-73f0-415d-8743-01dd2f26e2b7}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar 1", + "mn": "{0d81b309-da59-4646-812d-ed9212679e27}", + "p": { + "a": 0, + "k": [ + 166.49999999999997, + 144.89999999999998 + ] + }, + "or": { + "a": 0, + "k": 103.60950469970703 + }, + "ir": { + "a": 0, + "k": 51.804752349853516 + }, + "r": { + "a": 0, + "k": 147.41429138183594 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "hd": true, + "nm": "Stroke", + "mn": "{5271148f-841e-4e99-9f23-e0b201b46def}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5019607843137255, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{c72fab9f-6a71-4e30-966c-1b863389d19a}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 166.49999999999997, + 144.89999999999998 + ] + }, + "p": { + "a": 1, + "k": [ + { + "t": 0, + "s": [ + 106.19999999999997, + 126.89999999999998 + ], + "h": 0, + "o": { + "x": [ + 0.3333333333333333 + ], + "y": [ + 0 + ] + }, + "i": { + "x": [ + 0.6666666666666666 + ], + "y": [ + 1 + ] + }, + "e": [ + 413.99999999999994, + 413.09999999999997 + ] + }, + { + "t": 180, + "s": [ + 413.99999999999994, + 413.09999999999997 + ] + } + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } + ] + } +], +"layers": [ + { + "ty": 0, + "ddd": 0, + "nm": "Composition", + "mn": "{e3aa5446-47d2-454e-8d20-ed3c5f15612e}", + "ip": 0, + "op": 180, + "ind": 2, + "st": 0, + "sr": 1, + "ks": { + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 50, + 50 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "refId": "{4d838004-a221-48cb-966f-399347c5acb8}", + "w": 512, + "h": 512 + }, + { + "ty": 0, + "ddd": 0, + "nm": "Remapped", + "mn": "{0f7b917c-b0e8-450f-bb63-812dff786620}", + "ip": 0, + "op": 180, + "ind": 1, + "st": 0, + "sr": 1, + "tm": { + "a": 1, + "k": [ + { + "t": 0, + "s": [0], + "o": { "x": 0, "y": 0}, + "i": { "x": 1, "y": 1} + }, + { + "t": 30, + "s": [3], + "o": { "x": 0, "y": 0}, + "i": { "x": 1, "y": 1} + }, + { + "t": 60, + "s": [1.5], + "o": { "x": 0, "y": 0}, + "i": { "x": 1, "y": 1} + }, + { + "t": 180, + "s": [3], + "o": { "x": 0, "y": 0}, + "i": { "x": 1, "y": 1} + } + ] + }, + "ks": { + "a": { + "a": 0, + "k": [ + 512, + 512 + ] + }, + "p": { + "a": 0, + "k": [ + 512, + 512 + ] + }, + "s": { + "a": 0, + "k": [ + 50, + 50 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "refId": "{4d838004-a221-48cb-966f-399347c5acb8}", + "w": 512, + "h": 512 + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/repeater.json b/examples/repeater.json new file mode 100644 index 00000000..274a5224 --- /dev/null +++ b/examples/repeater.json @@ -0,0 +1,227 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{33a02914-c5a9-4c4e-a0bd-0ec07f05b204}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{9eb62fdc-6d5b-4771-94c0-ebdafbd7a54e}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{bfbf6254-ff78-4d00-9d09-eafe4e34b732}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{5a453691-6b60-4bd3-bc43-e28b7a0ebc48}", + "p": { + "a": 0, + "k": [ + 80, + 120 + ] + }, + "or": { + "a": 0, + "k": 80 + }, + "ir": { + "a": 0, + "k": 40 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{b0ba4cf0-3a1b-45a3-8912-d0ed2bdd2082}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0, + 0.5, + 1 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 1 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{0c2313ae-ccff-4e71-9e00-81649390d850}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "rp", + "nm": "Repeater", + "mn": "{a9e13270-7dd8-4520-b5a1-c1c9cf96286b}", + "c": { + "a": 0, + "k": 4 + }, + "o": { + "a": 0, + "k": 0 + }, + "m": 1, + "tr": { + "a": { + "a": 0, + "k": [ + 80, + 120 + ] + }, + "p": { + "a": 0, + "k": [ + 130, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 137.508 + }, + "so": { + "a": 0, + "k": 100 + }, + "eo": { + "a": 0, + "k": 50 + } + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 65.33731343283583, + 117.77910447761194 + ] + }, + "p": { + "a": 0, + "k": [ + 73.93432835820896, + 93.70746268656717 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/rounded_corners.json b/examples/rounded_corners.json new file mode 100644 index 00000000..72c23ca7 --- /dev/null +++ b/examples/rounded_corners.json @@ -0,0 +1,188 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{9199543e-3552-4e51-a802-623f2a4a2ca1}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{57cff206-c227-4a14-a679-195157be886b}", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "or": { + "a": 0, + "k": 222.72242736816406 + }, + "ir": { + "a": 0, + "k": 111.36121368408203 + }, + "r": { + "a": 0, + "k": 358.67291259765625 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "rd", + "nm": "Rounded Corners", + "mn": "{dcd7570f-5105-485b-bd43-42ad990b01e8}", + "r": { + "a": 0, + "k": 50 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "fl", + "hd": true, + "nm": "Fill", + "mn": "{a1bcc159-6916-4718-841d-a99140c0e74b}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "r": 1 + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} diff --git a/examples/sound.mp3 b/examples/sound.mp3 new file mode 100644 index 00000000..05ed08a2 Binary files /dev/null and b/examples/sound.mp3 differ diff --git a/examples/star.json b/examples/star.json new file mode 100644 index 00000000..2bd26a13 --- /dev/null +++ b/examples/star.json @@ -0,0 +1,159 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, + +"layers": [ + { + "ty": 4, + "ddd": 0, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ip": 0, + "op": 180, + "ind": 0, + "st": 0, + "sr": 1, + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{9199543e-3552-4e51-a802-623f2a4a2ca1}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "or": { + "a": 0, + "k": 200 + }, + "ir": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.979995422293431, + 0.28000305180437934 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 30 + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/stroke.json b/examples/stroke.json new file mode 100644 index 00000000..9846b482 --- /dev/null +++ b/examples/stroke.json @@ -0,0 +1,156 @@ + +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{57cff206-c227-4a14-a679-195157be886b}", + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "or": { + "a": 0, + "k": 200 + }, + "ir": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "tm", + "nm": "Trim Path", + "mn": "{dcd7570f-5105-485b-bd43-42ad990b01e8}", + "s": { + "a": 0, + "k": 0 + }, + "e": { + "a": 0, + "k": 100 + }, + "o": { + "a": 0, + "k": 0 + }, + "m": 1 + }, + { + "ty": "st", + "nm": "Stroke", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.98, + 0.28 + ] + }, + "lc": 2, + "lj": 2, + "ml": 3, + "w": { + "a": 0, + "k": 20 + }, + "d": [ + { + "n": "o", + "nm": "offset", + "v": {"a": 0, "k": 0} + }, + { + "n": "d", + "nm": "dash", + "v": {"a": 0, "k": 100} + }, + { + "n": "g", + "nm": "gap", + "v": {"a": 0, "k": 0} + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/text-document.json b/examples/text-document.json new file mode 100644 index 00000000..24dafbcd --- /dev/null +++ b/examples/text-document.json @@ -0,0 +1,75 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 300, + "h": 100, + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "fPath": "https://fonts.gstatic.com/s/ubuntu/v15/4iCp6KVjbNBYlgoKejZftWyI.ttf", + "fFamily": "Ubuntu", + "fStyle": "Light Italic", + "fName": "Ubuntu Light Italic", + "origin": 3 + } + ] + }, + "layers": [ + { + "nm": "Text Layer", + "ty": 5, + "sr": 1, + "ks": { + "p": { + "k": [ + 5, + 80 + ], + "a": 0 + } + }, + "ip": 0, + "op": 120, + "st": 0, + "t": { + "a": [], + "d": { + "k": [ + { + "s": { + "f": "Ubuntu Light Italic", + "fc": [ + 0, + 0, + 0 + ], + "s": 100, + "t": "Hello", + "j": 0 + }, + "t": 0 + } + ] + }, + "m": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + } + }, + "p": {} + } + } + ] +} + + + + diff --git a/examples/text-selector.json b/examples/text-selector.json new file mode 100644 index 00000000..d36ae1fc --- /dev/null +++ b/examples/text-selector.json @@ -0,0 +1,177 @@ +{ + "v": "5.9.6", + "fr": 60, + "ip": 0, + "op": 60, + "w": 512, + "h": 350, + "assets": [], + "fonts": { + "list": [ + { + "origin": 0, + "fPath": "", + "fClass": "", + "fFamily": "Sans", + "fWeight": "", + "fStyle": "Regular", + "fName": "Sans" + } + ] + }, + "layers": [ + { + "ty": 5, + "sr": 1, + "ip": 0, + "op": 60, + "st": 0, + "ks": { + "p": { + "a": 0, + "k": [ + 256, + 70, + 0 + ] + } + }, + "t": { + "d": { + "k": [ + { + "s": { + "s": 70, + "f": "Sans", + "t": "Hello World\rthe quick brown\rfox jumps over\rthe lazy dog", + "ls": 0, + "j": 2, + "fc": [ + 0, + 0, + 0 + ], + "sc": [ + 0, + 0, + 0 + ], + "sw": 0, + "of": true + }, + "t": 0 + } + ] + }, + "p": {}, + "m": { + "g": 1, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 2 + } + }, + "a": [ + { + "nm": "Text Range", + "s": { + "t": 0, + "o": { + "a": 0, + "k": 0 + }, + "s": { + "a": 0, + "k": 60 + }, + "e": { + "a": 0, + "k": 75 + }, + "a": { + "a": 0, + "k": 100 + }, + "b": 1, + "rn": 0, + "sh": 1, + "xe": { + "a": 0, + "k": 0 + }, + "ne": { + "a": 0, + "k": 0 + }, + "sm": { + "a": 0, + "k": 100 + }, + "r": 1 + }, + "a": { + "p": { + "a": 0, + "k": [0, 0] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + }, + "fc": { + "a": 0, + "k": [0.196, 0.314, 0.69] + }, + "fh": { + "a": 0, + "k": 0 + }, + "fs": { + "a": 0, + "k": 0 + }, + "fb": { + "a": 0, + "k": 0 + }, + "sc": { + "a": 0, + "k": [ + 1, + 0, + 0 + ] + }, + "sw": { + "a": 0, + "k": 0 + }, + "t": { + "a": 0, + "k": 0 + } + } + } + ] + } + }, + { + "ty": 1, + "ip": 0, + "op": 60, + "st": 0, + "ks": {}, + "sc": "#ffffff", + "sw": 512, + "sh": 350 + } + ] +} diff --git a/examples/text.json b/examples/text.json new file mode 100644 index 00000000..34a029c2 --- /dev/null +++ b/examples/text.json @@ -0,0 +1,118 @@ +{ + "v": "5.5.2", + "fr": 60, + "ip": 0, + "op": 120, + "w": 512, + "h": 512, + "ddd": 0, + "assets": [], + "fonts": { + "list": [ + { + "fFamily": "sans", + "fName": "sans", + "fStyle": "Regular" + } + ] + }, + "layers": [ + { + "ddd": 0, + "ty": 5, + "sr": 1, + "ks": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + }, + "p": { + "k": [ + 30, + 200 + ], + "a": 0 + }, + "s": { + "k": [ + 100, + 100 + ], + "a": 0 + }, + "r": { + "k": 0, + "a": 0 + }, + "o": { + "k": 100, + "a": 0 + }, + "sk": { + "k": 0, + "a": 0 + }, + "sa": { + "k": 0, + "a": 0 + } + }, + "ao": 0, + "ip": 0, + "op": 120, + "st": 0, + "bm": 0, + "ind": 0, + "t": { + "a": [], + "d": { + "k": [ + { + "s": { + "f": "sans", + "fc": [ + 1, + 0, + 0, + 1 + ], + "s": 200, + "t": "Text", + "j": 0 + }, + "t": 0 + }, + { + "s": { + "f": "sans", + "fc": [ + 0, + 1, + 0, + 1 + ], + "s": 200, + "t": "Here", + "j": 0 + }, + "t": 60 + } + ] + }, + "m": { + "a": { + "k": [ + 0, + 0 + ], + "a": 0 + } + }, + "p": {} + } + } + ] +} diff --git a/examples/text_shape.png b/examples/text_shape.png new file mode 100644 index 00000000..a6b8efa1 Binary files /dev/null and b/examples/text_shape.png differ diff --git a/examples/thumbs-up.png b/examples/thumbs-up.png new file mode 100644 index 00000000..7b5f1070 Binary files /dev/null and b/examples/thumbs-up.png differ diff --git a/examples/transform.json b/examples/transform.json new file mode 100644 index 00000000..32ffc7e2 --- /dev/null +++ b/examples/transform.json @@ -0,0 +1,273 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{a3bb98c7-d0dd-4484-b6da-74a0e70eaf2f}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 2, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Anchor", + "mn": "{04f9b742-3603-49fa-9552-ea04de1a3f33}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "el", + "nm": "Ellipse", + "mn": "{4251e46a-bb13-464b-913c-e67c44a218da}", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 32, + 32 + ] + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{7d3070ed-88a3-41aa-a62e-7db8df1bd312}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.9411764705882353, + 0.11372549019607843, + 0.0392156862745098 + ] + }, + "r": 1 + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 1, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Transformed", + "mn": "{d00298c4-66b4-4ae4-a730-22c1eb85c188}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + }, + "sk": { + "a": 0, + "k": 0 + }, + "sa": { + "a": 0, + "k": 0 + } + }, + "shapes": [ + { + "ty": "rc", + "nm": "Rectangle 1", + "mn": "{bf8ad877-113b-4df8-a2e2-3bb4af32edf7}", + "p": { + "a": 0, + "k": [ + 252.75223880597017, + 250.60298507462684 + ] + }, + "s": { + "a": 0, + "k": [ + 319.8089552238806, + 330.98507462686564 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "nm": "Fill 1", + "mn": "{b9040dc8-0753-4a6e-b5f1-d508d17bbd4f}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.19607843137254902, + 0.3137254901960784, + 0.6901960784313725 + ] + }, + "r": 1 + } + ] + }, + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Reference", + "mn": "{8f351be7-8a51-4310-9dc3-59ed21594815}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "rc", + "nm": "Rectangle", + "mn": "{cb4f7b74-bed1-493b-a0e6-01b00566aedd}", + "p": { + "a": 0, + "k": [ + 252.75223880597017, + 250.60298507462684 + ] + }, + "s": { + "a": 0, + "k": [ + 319.8089552238806, + 330.98507462686564 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "fl", + "nm": "Fill", + "mn": "{05064670-7e14-4141-89c1-e0f0f3a1c57d}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 0.1607843137254902, + 0.1843137254901961, + 0.4588235294117647 + ] + }, + "r": 1 + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/trim_path.json b/examples/trim_path.json new file mode 100644 index 00000000..05d077e9 --- /dev/null +++ b/examples/trim_path.json @@ -0,0 +1,211 @@ +{ +"v": "5.7.1", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{57cff206-c227-4a14-a679-195157be886b}", + "p": { + "a": 0, + "k": [ + 128, + 128 + ] + }, + "or": { + "a": 0, + "k": 100 + }, + "ir": { + "a": 0, + "k": 50 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "el", + "nm": "Ellipse", + "mn": "{74587b40-1ef1-445d-b9ab-02b8a42a96aa}", + "p": { + "a": 0, + "k": [ + 384, + 128 + ] + }, + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + } + }, + { + "ty": "rc", + "nm": "Rect", + "mn": "{0776f2df-2619-415c-b10d-f648f2edfa0f}", + "d": 1, + "p": { + "a": 0, + "k": [ + 128, + 384 + ] + }, + "s": { + "a": 0, + "k": [ + 200, + 200 + ] + }, + "r": { + "a": 0, + "k": 0 + } + }, + { + "ty": "sr", + "nm": "Triangle", + "mn": "{db373594-d0ae-44ff-9295-30ff72616af2}", + "p": { + "a": 0, + "k": [ + 384, + 384 + ] + }, + "or": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "pt": { + "a": 0, + "k": 3 + }, + "sy": 2, + "os": { + "a": 0, + "k": 0 + } + }, + { + "ty": "tm", + "nm": "Trim Path", + "mn": "{dcd7570f-5105-485b-bd43-42ad990b01e8}", + "s": { + "a": 0, + "k": 0 + }, + "e": { + "a": 0, + "k": 50 + }, + "o": { + "a": 0, + "k": 0 + }, + "m": 1 + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 20 + } + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-32-gb62899be" +} +} diff --git a/examples/zig-zag.json b/examples/zig-zag.json new file mode 100644 index 00000000..b87d81e6 --- /dev/null +++ b/examples/zig-zag.json @@ -0,0 +1,178 @@ +{ +"v": "5.5.7", +"ip": 0, +"op": 180, +"nm": "Animation", +"mn": "{8f1618e3-6f83-4531-8f65-07dd4b68ee2e}", +"fr": 60, +"w": 512, +"h": 512, +"assets": [ +], +"layers": [ + { + "ddd": 0, + "ty": 4, + "ind": 0, + "st": 0, + "ip": 0, + "op": 180, + "nm": "Layer", + "mn": "{85f37d8b-1792-4a4f-82d2-1b3b6d829c07}", + "ks": { + "a": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + }, + "shapes": [ + { + "ty": "gr", + "nm": "PolyStar", + "mn": "{9199543e-3552-4e51-a802-623f2a4a2ca1}", + "it": [ + { + "ty": "sr", + "nm": "PolyStar", + "mn": "{57cff206-c227-4a14-a679-195157be886b}", + "p": { + "a": 0, + "k": [ + 256, + 256 + ] + }, + "or": { + "a": 0, + "k": 222.72242736816406 + }, + "ir": { + "a": 0, + "k": 111.36121368408203 + }, + "r": { + "a": 0, + "k": 358.67291259765625 + }, + "pt": { + "a": 0, + "k": 5 + }, + "sy": 1, + "os": { + "a": 0, + "k": 0 + }, + "is": { + "a": 0, + "k": 0 + } + }, + { + "ty": "zz", + "nm": "Zig Zag", + "mn": "{b4af429a-546e-4728-a869-711a404c55ae}", + "r": { + "a": 0, + "k": 0 + }, + "s": { + "a": 0, + "k": 10 + }, + "pt": { + "a": 0, + "k": 2 + } + }, + { + "ty": "st", + "nm": "Stroke", + "mn": "{0930ce27-c8f9-4371-b0cf-111a859abfaf}", + "o": { + "a": 0, + "k": 100 + }, + "c": { + "a": 0, + "k": [ + 1, + 0.9803921568627451, + 0.2823529411764706 + ] + }, + "lc": 2, + "lj": 2, + "ml": 0, + "w": { + "a": 0, + "k": 3 + } + }, + { + "ty": "tr", + "a": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "p": { + "a": 0, + "k": [ + 249.3134328358209, + 254.47164179104476 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } + } + ] + } + ] + } +], +"meta": { + "g": "Glaxnimate 0.4.6-26-g7b05e75c" +} +} + diff --git a/expressions/index.html b/expressions/index.html new file mode 100644 index 00000000..5b4d4bcd --- /dev/null +++ b/expressions/index.html @@ -0,0 +1,3487 @@ + + + + + + + + + + + + + + Expressions - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Expressions

+ + +

Properties can have expressions associated with them, +when this is the case the value of such properties can be modified by using the expression.

+

The expression language is based on JavaScript / ECMAScript.

+

For the most part it uses what is described in the After Effects expressions.

+

More resources on AE expressions:

+ +

Global objects

+

$bm_rt

+ + + + + + + + + + + + + + + + + +
Name$bm_rt
TypeDepends on the property
Description +

Output value for the expression

+
Notes +

Must be declared and be assigned a value in every expression

+
+

The special variable $bm_rt is used to determine the value of the expression.

+

This variable must be declared by the expression and must have a value compatible with the property;

+
var $bm_rt;
+$bm_rt = 60;
+
+
+ + + + + + + + + + + + + +
+
+ + +
+
+
+ + +
+
+
+
+
+
+ + +
+

time

+ + + + + + + + + + + + + + + + + +
Nametime
Typenumber
Description +

The current time within the composition in seconds

+
Notes +

Read only

+
+
+ + + + + + + +
+
+ + +
+
+
+
+
+
+ + +
+

value

+ + + + + + + + + + + + + + + + + +
Namevalue
TypeDepends on the property
Description +

The value the property would have without expressions

+
Notes +

Read only

+
+
+ + + + + + + +
+
+ + +
+
+
+
+
+
+ + +
+

thisProperty

+ + + + + + + + + + + + + + + + + +
NamethisProperty
TypeProperty
Description +

Property the expression is operating on

+
Notes +

Read only

+
+

thisComp

+ + + + + + + + + + + + + + + + + +
NamethisComp
TypeComposition
Description +

Composition the property is in

+
Notes +

Read only

+
+

thisLayer

+ + + + + + + + + + + + + + + + + +
NamethisLayer
TypeLayer
Description +

Layer the property is in

+
Notes +

Read only

+
+

Animation Structure functions

+

comp()

+

Synopsis

+
comp (
+    name: string
+): Composition
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
namestring +

Composition name

+
+

Return

+ + + + + + + + + +
TypeComposition
Description +

Composition object matching the given name

+
+

Misc Functions

+

posterizeTime()

+

Synopsis

+
posterizeTime (
+    fps: number
+)
+
+

+

The rest of the expression will only be updated this many times per second

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
fpsnumber +

Frames per second

+
+

timeToFrames()

+

Synopsis

+
timeToFrames (
+    time: number = time + thisComp.displayStartTime
+    fps: number = 1.0 / thisComp.frameDuration
+): number
+
+

+

Converts a time in seconds to a number of frames

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
timenumbertime + thisComp.displayStartTime +

Time in seconds

+
fpsnumber1.0 / thisComp.frameDuration +

Frames per second

+
+

Return

+ + + + + + + + + +
Typenumber
Description +

Number of frames

+
+

framesToTime()

+

Synopsis

+
framesToTime (
+    frames: number
+    fps: number = 1.0 / thisComp.frameDuration
+): number
+
+

+

Converts a number of frames to a time in seconds

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
framesnumber +

Number of frames

+
fpsnumber1.0 / thisComp.frameDuration +

Frames per second

+
+

Return

+ + + + + + + + + +
Typenumber
Description +

Time in seconds

+
+

rgbToHsl()

+

Synopsis

+
rgbToHsl (
+    rgb: array[3]|array[4]
+): array[3]|array[4]
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
rgbarray[3]|array[4] +

RGB(A) color, with components in 0, 1

+
+

Return

+ + + + + + + + + +
Typearray[3]|array[4]
Description +

HSL(A) color, with components in 0, 1

+
+

hslToRgb()

+

Synopsis

+
hslToRgb (
+    hsl: array[3]|array[4]
+): array[3]|array[4]
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
hslarray[3]|array[4] +

HSL(A) color, with components in 0, 1

+
+

Return

+ + + + + + + + + +
Typearray[3]|array[4]
Description +

RGB(A) color, with components in 0, 1

+
+

createPath()

+

Synopsis

+
createPath (
+    points: array
+    in_tangents: array = []
+    out_tangents: array = []
+    is_closed: boolean = true
+): Path
+
+

+

Creates bezier path data

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointsarray +

Array of points (each point is a list with 2 numbers)

+
in_tangentsarray[] +

Array of in tangents correponding to the point with the same index

+
out_tangentsarray[] +

Array of out tangents correponding to the point with the same index

+
is_closedbooleantrue +

Whether the path is closed

+
+

Return

+ + + + + +
TypePath
+

Math functions

+

add()

+

Synopsis

+
add (
+    a: any
+    b: any
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
aany
bany
+

Return

+ + + + + +
Typeany
+

If a and b are numbers, it will return their sum.

+

If they string, their concatenation.

+

If they are vectors, their element-wise sum.

+

If one is a vector and the other a number, it will return the sum of the number by the first element of the vector.

+

This function is also available as $bm_sum and sum.

+

sub()

+

Synopsis

+
sub (
+    a: any
+    b: any
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
aany
bany
+

Return

+ + + + + +
Typeany
+

If a and b are numbers, or can be converted to numbers, it will return their difference.

+

If they are vectors, their element-wise difference.

+

This function is also avilable as $bm_sub.

+

mul()

+

Synopsis

+
mul (
+    a: any
+    b: any
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
aany
bany
+

Return

+ + + + + +
Typeany
+

If a and b are numbers, or can be converted to numbers, it will return their product.

+

If one of them is a vector and the other a number, it will return a vector with each element multiplied by the number.

+

This function is also avilable as $bm_mul.

+

div()

+

Synopsis

+
div (
+    a: any
+    b: any
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
aany
bany
+

Return

+ + + + + +
Typeany
+

If a and b are numbers, or can be converted to numbers, it will return their division.

+

If one of them is a vector and the other a number, it will return a vector with each element divided by the number.

+

This function is also avilable as $bm_div.

+

mod()

+

Synopsis

+
mod (
+    a: any
+    b: any
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
aany
bany
+

Return

+ + + + + +
Typeany
+

clamp()

+

Synopsis

+
clamp (
+    value: number
+    minimum: number
+    maximum: number
+): number
+
+

+

Clamps a value inside a range

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
valuenumber +

The value to clamp

+
minimumnumber +

Minimum value

+
maximumnumber +

Maximum value

+
+

Return

+ + + + + +
Typenumber
+

normalize()

+

Synopsis

+
normalize (
+    vector: array
+): number
+
+

+

Divides a vector by its length

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
vectorarray
+

Return

+ + + + + + + + + +
Typenumber
Description +

same as div(vector, length(vector))

+
+

length()

+

Synopsis

+
length (
+    vector: array
+): number
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
vectorarray
+

Return

+ + + + + + + + + +
Typenumber
Description +

length of vector

+
+

Synopsis

+
length (
+    a: array
+    b: array
+): number
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
aarray
barray
+

Return

+ + + + + + + + + +
Typenumber
Description +

Distance between a and b.

+
+

looAt()

+

Synopsis

+
lookAt (
+    from_point: array[3]
+    to_point: array[3]
+): number
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
from_pointarray[3]
to_pointarray[3]
+

Return

+ + + + + + + + + +
Typenumber
Description +

length of vector

+
+

seedRandom()

+

Synopsis

+
seedRandom (
+    seed: number
+)
+
+

+

Sets the seed for random functions

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
seednumber
+

random()

+

Synopsis

+
random (): number
+
+

Return

+ + + + + + + + + +
Typenumber
Description +

Random number between 0 and 1

+
+

Synopsis

+
random (
+    max: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
maxnumber|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Random number between 0 and max, element wise if the argument is an array

+
+

Synopsis

+
random (
+    min: number|array
+    max: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
minnumber|array
maxnumber|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Random number between min and max, element wise if the arguments are arrays

+
+

linear()

+

Synopsis

+
linear (
+    t: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between 0 and 1

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Linear interpolation between value1 and value2

+
+

Synopsis

+
linear (
+    t: number
+    t_min: number
+    t_max: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between t_min and t_max

+
t_minnumber +

Lower bound for the t range

+
t_maxnumber +

Lower bound for the t range

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Linear interpolation between value1 and value2, t is first normalized inside t_min and t_max

+
+

ease()

+

Works the same as linear() but with a smooth cubic interpolation.

+

Synopsis

+
ease (
+    t: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between 0 and 1

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Interpolation between value1 and value2

+
+

Synopsis

+
ease (
+    t: number
+    t_min: number
+    t_max: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between t_min and t_max

+
t_minnumber +

Lower bound for the t range

+
t_maxnumber +

Lower bound for the t range

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Interpolation between value1 and value2, t is first normalized inside t_min and t_max

+
+

easeIn()

+

Interpolation, starts the same as ease() and ends the same as linear()

+

Synopsis

+
easeIn (
+    t: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between 0 and 1

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Interpolation between value1 and value2

+
+

Synopsis

+
easeIn (
+    t: number
+    t_min: number
+    t_max: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between t_min and t_max

+
t_minnumber +

Lower bound for the t range

+
t_maxnumber +

Lower bound for the t range

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Interpolation between value1 and value2, t is first normalized inside t_min and t_max

+
+

easeOut()

+

Interpolation, starts the same as linear() and ends the same as ease()

+

Synopsis

+
easeOut (
+    t: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between 0 and 1

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Interpolation between value1 and value2

+
+

Synopsis

+
easeOut (
+    t: number
+    t_min: number
+    t_max: number
+    value1: number|array
+    value2: number|array
+): number|array
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Interpolation factor between t_min and t_max

+
t_minnumber +

Lower bound for the t range

+
t_maxnumber +

Lower bound for the t range

+
value1number|array
value2number|array
+

Return

+ + + + + + + + + +
Typenumber|array
Description +

Interpolation between value1 and value2, t is first normalized inside t_min and t_max

+
+

degreesToRadians()

+

Synopsis

+
degreesToRadians (
+    degrees: number
+): number
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
degreesnumber +

Angle in degrees

+
+

Return

+ + + + + + + + + +
Typenumber
Description +

Angle in radians

+
+

radiansToDegrees()

+

Synopsis

+
radiansToDegrees (
+    radians: number
+): number
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
radiansnumber +

Angle in radians

+
+

Return

+ + + + + + + + + +
Typenumber
Description +

Angle in degrees

+
+ + +

Property

+

Property.value

+ + + + + + + + + + + + + + + + + +
Namevalue
TypeDepends on the property
Description +

The current value the property

+
Notes +

Read only

+
+

Property.numKeys

+ + + + + + + + + + + + + + + + + +
NamenumKeys
Typenumber
Description +

Number of keyframes

+
Notes +

Read only

+
+

Property.propertyIndex

+ + + + + + + + + + + + + + + + + +
NamepropertyIndex
Typenumber
Description +

Value of ix in the JSON for this property

+
Notes +

Read only

+
+

Property.valueAtTime()

+

Synopsis

+
valueAtTime (
+    t: number
+): any
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Time in seconds

+
+

Return

+ + + + + + + + + +
TypeDepends on the property
Description +

The value of the property at the given time (without expressions)

+
+

Property.getVelocityAtTime()

+

Synopsis

+
getVelocityAtTime (
+    t: number
+): any
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Time in seconds

+
+

Return

+ + + + + + + + + +
TypeDepends on the property
Description +

The rate of change for the property, with the same dimensions as the value

+
+

Property.getSpeedAtTime()

+

Synopsis

+
getSpeedAtTime (
+    t: number
+): number
+
+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
tnumber +

Time in seconds

+
+

Return

+ + + + + + + + + +
Typenumber
Description +

The rate of change for the property as a scalar

+
+

Property.smooth()

+

Synopsis

+
smooth (
+    width: number
+    samples: number
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
widthnumber
samplesnumber
+

Return

+ + + + + +
TypeDepends on the property
+

Property.loopIn()

+

Synopsis

+
loopIn (
+    type: string
+    duration: number
+    wrap: boolean
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
typestring
durationnumber
wrapboolean
+

Return

+ + + + + +
TypeDepends on the property
+

Property.loopOut()

+

Synopsis

+
loopOut (
+    type: string
+    duration: number
+    wrap: boolean
+): any
+
+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
typestring
durationnumber
wrapboolean
+

Return

+ + + + + +
TypeDepends on the property
+

Composition

+

Composition object

+
+ + + + + + + +
+
+ + +
+
+
+
+
+
+ + +
+

As a function

+

As a function a composition object can give you access to the layers by name or index

+
+ + + + + + + +
+
+ + +
+
+
+
+
+
+ + +
+

Composition.numLayers

+ + + + + + + + + + + + + +
NamenumLayers
Typenumber
Description +

Number of layers in the composition

+
+

Composition.width

+ + + + + + + + + + + + + +
Namewidth
Typenumber
Description +

Width of the composition, same as w in the JSON

+
+

Composition.height

+ + + + + + + + + + + + + +
Nameheight
Typenumber
Description +

Height of the composition, same as h in the JSON

+
+

Composition.displayStartTime

+ + + + + + + + + + + + + +
NamedisplayStartTime
Typenumber
Description +

Start time of the composition, in seconds. Similar to ip in the JSON but converted into seconds

+
+

Composition.frameDuration

+ + + + + + + + + + + + + +
NameframeDuration
Typenumber
Description +

Duration of a frame in second, reciprocal of frames per second

+
+

Composition.pixelAspect

+ + + + + + + + + + + + + +
NamepixelAspect
Typenumber
Description +

Pixel aspect ratio, generally 1

+
+

Composition.layer()

+

Synopsis

+
layer (
+    layer: number|string
+): Layer
+
+

+

Returns the given layer

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
layernumber|string +

Layer name or index

+
+

Return

+ + + + + +
TypeLayer
+ + +

Layer

+

Layer object.

+

Note that it also has all the attributes from Transform.

+

Layer.index

+ + + + + + + + + + + + + +
Nameindex
Typenumber
Description +

Layer index, same as ind in the JSON

+
+

Layer.inPoint

+ + + + + + + + + + + + + +
NameinPoint
Typenumber
Description +

Same as ip in the JSON but in seconds

+
+

Layer.outPoint

+ + + + + + + + + + + + + +
NameoutPoint
Typenumber
Description +

Same as op in the JSON but in seconds

+
+

Layer.startTime

+ + + + + + + + + + + + + +
NamestartTime
Typenumber
Description +

Same as st in the JSON but in seconds

+
+

Layer.transform

+

Transform attributes can also be accessed from the layer object directly

+ + + + + + + + + + + + + +
Nametransofrm
TypeTransform
Description
+

Layer.source

+ + + + + + + + + + + + + +
Namesource
Typestring
Description +

For layers referencing an asset, the id of that asses. (Same as refId in the JSON)

+
+

Layer.width

+ + + + + + + + + + + + + +
Namewidth
Typenumber
Description +

Same as Layer.sourceRectAtTime().width

+
+

Layer.height

+ + + + + + + + + + + + + +
Nameheight
Typenumber
Description +

Same as Layer.sourceRectAtTime().height

+
+

Layer.hasParent

+ + + + + + + + + + + + + +
NamehasParent
Typeboolean
Description +

Whether the layer has a parent

+
+

Layer.parent

+ + + + + + + + + + + + + +
Nameparent
TypeLayer
Description +

Parent layer

+
+

Layer.sourceRectAtTime

+

Synopsis

+
sourceRectAtTime (): object
+
+

Return

+ + + + + + + + + +
Typeobject
Description +

Object with these attributes

+
+

Layer.effect

+

Synopsis

+
effect (
+    effect: number|string
+): Effect
+
+

+

Returns the given effect

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
effectnumber|string +

Name or index

+
+

Return

+ + + + + +
TypeEffect
+

Layer.contents

+

Synopsis

+
contents (
+    shape: number|string
+): Shape
+
+

+

For shape layers, returns the given shape

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
shapenumber|string +

Name or index

+
+

Return

+ + + + + +
TypeShape
+

Layer space transforms

+

These methods convert between coordinates systems within a layer.

+

Some of these functions have a Vec suffix, which means they should be used +for difference between points (the version without this suffix is for points).

+

Layer.toComp

+

Synopsis

+
toComp (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a point from Layer coordinates to composition coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Point

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.fromComp

+

Synopsis

+
toComp (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a point from composition coordinates to Layer coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Point

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.toCompVec

+

Synopsis

+
toComp (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a vector from Layer coordinates to composition coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Vector

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.fromCompVec

+

Synopsis

+
toComp (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a vector from composition coordinates to Layer coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Vector

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.toWorld

+

Synopsis

+
toWorld (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a point from Layer coordinates to world coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Point

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.fromWorld

+

Synopsis

+
toWorld (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a point from world coordinates to Layer coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Point

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.toWorldVec

+

Synopsis

+
toWorld (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a vector from Layer coordinates to world coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Vector

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+

Layer.fromWorldVec

+

Synopsis

+
toWorld (
+    point: Array
+    time: number = time
+): Array
+
+

+

Maps a vector from world coordinates to Layer coordinates

+

+

Parameters

+ + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
pointArray +

Vector

+
timenumbertime +

Time

+
+

Return

+ + + + + +
TypeArray
+ + +

Transform

+ + + + + + + + + + + + + +
NameanchorPoint
Typearray[2]
Description +

Value of a

+
+ + + + + + + + + + + + + +
Nameposition
Typearray[2]
Description +

Value of p

+
+ + + + + + + + + + + + + +
Namescale
Typenumber
Description +

Value of s

+
+ + + + + + + + + + + + + +
Namerotation
Typenumber
Description +

Value of r

+
+ + + + + + + + + + + + + +
Nameopacity
Typenumber
Description +

Value of o

+
+ + + + + + + + + + + + + +
Nameskew
Typenumber
Description +

Value of sk

+
+ + + + + + + + + + + + + +
NameskewAxis
Typenumber
Description +

Value of sa

+
+

Effect

+ + + + + + + + + + + + + +
Nameactive
Typeboolean
Description +

Whether the effect is active

+
+

Effect()

+

Synopsis

+
 (
+    property: number|string
+): number|Array
+
+

+

Returns the value for the given property of the effect

+

+

Parameters

+ + + + + + + + + + + + + +
NameTypeDefaultDescription
propertynumber|string +

Name or index of the property

+
+

Return

+ + + + + +
Typenumber|Array
+
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fonts/Karla-Bold.ttf b/fonts/Karla-Bold.ttf new file mode 100644 index 00000000..c805e5ee Binary files /dev/null and b/fonts/Karla-Bold.ttf differ diff --git a/fonts/Karla-Italic-VariableFont_wght.ttf b/fonts/Karla-Italic-VariableFont_wght.ttf new file mode 100644 index 00000000..e027584b Binary files /dev/null and b/fonts/Karla-Italic-VariableFont_wght.ttf differ diff --git a/fonts/Karla-VariableFont_wght.ttf b/fonts/Karla-VariableFont_wght.ttf new file mode 100644 index 00000000..e5bf8969 Binary files /dev/null and b/fonts/Karla-VariableFont_wght.ttf differ diff --git "a/fonts/Type-\303\230-Tones-Arboria-Black.otf" "b/fonts/Type-\303\230-Tones-Arboria-Black.otf" new file mode 100644 index 00000000..67c1d6bc Binary files /dev/null and "b/fonts/Type-\303\230-Tones-Arboria-Black.otf" differ diff --git "a/fonts/Type-\303\230-Tones-Arboria-Bold.otf" "b/fonts/Type-\303\230-Tones-Arboria-Bold.otf" new file mode 100644 index 00000000..451829df Binary files /dev/null and "b/fonts/Type-\303\230-Tones-Arboria-Bold.otf" differ diff --git a/fonts/fontawesome-webfont.eot b/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..7c79c6a6 Binary files /dev/null and b/fonts/fontawesome-webfont.eot differ diff --git a/fonts/fontawesome-webfont.svg b/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..45fdf338 --- /dev/null +++ b/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/fontawesome-webfont.ttf b/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..e89738de Binary files /dev/null and b/fonts/fontawesome-webfont.ttf differ diff --git a/fonts/fontawesome-webfont.woff b/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..8c1748aa Binary files /dev/null and b/fonts/fontawesome-webfont.woff differ diff --git a/img/LottieDocs.svg b/img/LottieDocs.svg new file mode 100644 index 00000000..b3237815 --- /dev/null +++ b/img/LottieDocs.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/img/chevron-left.svg b/img/chevron-left.svg new file mode 100644 index 00000000..f7e40349 --- /dev/null +++ b/img/chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/img/chevron-right.svg b/img/chevron-right.svg new file mode 100644 index 00000000..97a15495 --- /dev/null +++ b/img/chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/img/favicon.ico b/img/favicon.ico new file mode 100644 index 00000000..acac5dda Binary files /dev/null and b/img/favicon.ico differ diff --git a/img/grid1.png b/img/grid1.png new file mode 100644 index 00000000..a6c493ab Binary files /dev/null and b/img/grid1.png differ diff --git a/img/grid10.png b/img/grid10.png new file mode 100644 index 00000000..7c41953e Binary files /dev/null and b/img/grid10.png differ diff --git a/img/grid11.png b/img/grid11.png new file mode 100644 index 00000000..ef37b27e Binary files /dev/null and b/img/grid11.png differ diff --git a/img/grid12.png b/img/grid12.png new file mode 100644 index 00000000..3f100c41 Binary files /dev/null and b/img/grid12.png differ diff --git a/img/grid13.png b/img/grid13.png new file mode 100644 index 00000000..1a0d83f3 Binary files /dev/null and b/img/grid13.png differ diff --git a/img/grid14.png b/img/grid14.png new file mode 100644 index 00000000..deabc036 Binary files /dev/null and b/img/grid14.png differ diff --git a/img/grid15.png b/img/grid15.png new file mode 100644 index 00000000..1f0417a5 Binary files /dev/null and b/img/grid15.png differ diff --git a/img/grid16.png b/img/grid16.png new file mode 100644 index 00000000..984454f4 Binary files /dev/null and b/img/grid16.png differ diff --git a/img/grid17.png b/img/grid17.png new file mode 100644 index 00000000..fe48c9dd Binary files /dev/null and b/img/grid17.png differ diff --git a/img/grid18.png b/img/grid18.png new file mode 100644 index 00000000..3c84524b Binary files /dev/null and b/img/grid18.png differ diff --git a/img/grid19.png b/img/grid19.png new file mode 100644 index 00000000..2bfdd500 Binary files /dev/null and b/img/grid19.png differ diff --git a/img/grid2.png b/img/grid2.png new file mode 100644 index 00000000..c9eed3e9 Binary files /dev/null and b/img/grid2.png differ diff --git a/img/grid20.png b/img/grid20.png new file mode 100644 index 00000000..30e3faea Binary files /dev/null and b/img/grid20.png differ diff --git a/img/grid3.png b/img/grid3.png new file mode 100644 index 00000000..4617c9d9 Binary files /dev/null and b/img/grid3.png differ diff --git a/img/grid4.png b/img/grid4.png new file mode 100644 index 00000000..2a1f1801 Binary files /dev/null and b/img/grid4.png differ diff --git a/img/grid5.png b/img/grid5.png new file mode 100644 index 00000000..a1d710e0 Binary files /dev/null and b/img/grid5.png differ diff --git a/img/grid6.png b/img/grid6.png new file mode 100644 index 00000000..71b4148d Binary files /dev/null and b/img/grid6.png differ diff --git a/img/grid7.png b/img/grid7.png new file mode 100644 index 00000000..6044a419 Binary files /dev/null and b/img/grid7.png differ diff --git a/img/grid8.png b/img/grid8.png new file mode 100644 index 00000000..a4b6d44e Binary files /dev/null and b/img/grid8.png differ diff --git a/img/grid9.png b/img/grid9.png new file mode 100644 index 00000000..627dda51 Binary files /dev/null and b/img/grid9.png differ diff --git a/img/icon-right-arrow.svg b/img/icon-right-arrow.svg new file mode 100644 index 00000000..47a656b9 --- /dev/null +++ b/img/icon-right-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/img/icon-search.svg b/img/icon-search.svg new file mode 100644 index 00000000..d3ec9cac --- /dev/null +++ b/img/icon-search.svg @@ -0,0 +1,3 @@ + + + diff --git a/img/lf-logo-mini.svg b/img/lf-logo-mini.svg new file mode 100644 index 00000000..1f9887ef --- /dev/null +++ b/img/lf-logo-mini.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/img/logo-lottie.svg b/img/logo-lottie.svg new file mode 100644 index 00000000..e567487a --- /dev/null +++ b/img/logo-lottie.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/img/logo-react.svg b/img/logo-react.svg new file mode 100644 index 00000000..2d7c3d5d --- /dev/null +++ b/img/logo-react.svg @@ -0,0 +1,4 @@ + + + + diff --git a/img/logo-svelte.svg b/img/logo-svelte.svg new file mode 100644 index 00000000..89b33e8f --- /dev/null +++ b/img/logo-svelte.svg @@ -0,0 +1,4 @@ + + + + diff --git a/img/vue-logo.svg b/img/vue-logo.svg new file mode 100644 index 00000000..952f52c3 --- /dev/null +++ b/img/vue-logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/index.html b/index.html new file mode 100644 index 00000000..08737537 --- /dev/null +++ b/index.html @@ -0,0 +1,702 @@ + + + + + + + + + + + + + + Home - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + +
+
+
+ + +

A human's guide to the Lottie format

+

Lottie is a vector animation format, using JSON to represent its data.

+

+ This guide aims to provide a human-readable description of the format and how everything works within it. +

+ +
+ +
+
+
+

Lottie Format

+

This page describes values and other objects used throughout the Lottie format.

+
+
+

Lottie from Scratch

+

In this example, we'll build a simple lottie animation from scratch.

+
+
+

Lottie Playground

+ +
+
+
+
+ +

Lottie-Player

+

Easily embed and play Lottie animations in websites.

+
+
+ +

Lottie-React

+

Easily add Lottie animations to your React projects.

+
+
+ +

Lottie-Svelte

+

Svelte provides a Lottie player using the lottie-web library.

+
+
+ +

Lottie-Vue

+

Vue component for the Lottie Web Player.

+
+
+ +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/base.js b/js/base.js new file mode 100644 index 00000000..03aad550 --- /dev/null +++ b/js/base.js @@ -0,0 +1,225 @@ +function getSearchTerm() { + var sPageURL = window.location.search.substring(1); + var sURLVariables = sPageURL.split('&'); + for (var i = 0; i < sURLVariables.length; i++) { + var sParameterName = sURLVariables[i].split('='); + if (sParameterName[0] == 'q') { + return sParameterName[1]; + } + } +} + +$(document).ready(function() { + /** + * ------------------------------------------------------------------------ + * Taken from themes/mkdocs/js/base.js + * ------------------------------------------------------------------------ + */ + var search_term = getSearchTerm(), + $search_modal = $('#mkdocs_search_modal'), + $keyboard_modal = $('#mkdocs_keyboard_modal'); + + if (search_term) { + $search_modal.modal(); + } + + // make sure search input gets autofocus everytime modal opens. + $search_modal.on('shown.bs.modal', function() { + $search_modal.find('#mkdocs-search-query').focus(); + }); + + // Close search modal when result is selected + // The links get added later so listen to parent + $('#mkdocs-search-results').click(function(e) { + if ($(e.target).is('a')) { + $search_modal.modal('hide'); + } + }); + + if (typeof shortcuts !== 'undefined') { + // Populate keyboard modal with proper Keys + $keyboard_modal.find('.help.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.help]; + $keyboard_modal.find('.prev.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.previous]; + $keyboard_modal.find('.next.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.next]; + $keyboard_modal.find('.search.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.search]; + + // Keyboard navigation + document.addEventListener("keydown", function(e) { + if ($(e.target).is(':input')) return true; + var key = e.which || e.key || window.event && window.event.key; + var page; + switch (key) { + case shortcuts.next: + page = $('.navbar a[rel="next"]:first').prop('href'); + break; + case shortcuts.previous: + page = $('.navbar a[rel="prev"]:first').prop('href'); + break; + case shortcuts.search: + e.preventDefault(); + $keyboard_modal.modal('hide'); + $search_modal.modal('show'); + $search_modal.find('#mkdocs-search-query').focus(); + break; + case shortcuts.help: + $search_modal.modal('hide'); + $keyboard_modal.modal('show'); + break; + default: + break; + } + if (page) { + $keyboard_modal.modal('hide'); + window.location.href = page; + } + }); + } + + $('table').addClass('table table-striped table-hover'); + + // Improve the scrollspy behaviour when users click on a TOC item. + $(".bs-sidenav a").on("click", function() { + var clicked = this; + setTimeout(function() { + var active = $('.nav li.active a'); + active = active[active.length - 1]; + if (clicked !== active) { + $(active).parent().removeClass("active"); + $(clicked).parent().addClass("active"); + } + }, 50); + }); +}); + + +/** + * ------------------------------------------------------------------------ + * Taken from themes/mkdocs/js/base.js + * ------------------------------------------------------------------------ + */ + +$('#content-container').scrollspy({ + target: '.bs-sidebar', + offset: 50 +}); + +/* Prevent disabled links from causing a page reload */ +$("li.disabled a").click(function() { + event.preventDefault(); +}); + +// See https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes +// We only list common keys below. Obscure keys are omited and their use is discouraged. +var keyCodes = { + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 16: 'shift', + 17: 'ctrl', + 18: 'alt', + 19: 'pause/break', + 20: 'caps lock', + 27: 'escape', + 32: 'spacebar', + 33: 'page up', + 34: 'page down', + 35: 'end', + 36: 'home', + 37: '←', + 38: '↑', + 39: '→', + 40: '↓', + 45: 'insert', + 46: 'delete', + 48: '0', + 49: '1', + 50: '2', + 51: '3', + 52: '4', + 53: '5', + 54: '6', + 55: '7', + 56: '8', + 57: '9', + 65: 'a', + 66: 'b', + 67: 'c', + 68: 'd', + 69: 'e', + 70: 'f', + 71: 'g', + 72: 'h', + 73: 'i', + 74: 'j', + 75: 'k', + 76: 'l', + 77: 'm', + 78: 'n', + 79: 'o', + 80: 'p', + 81: 'q', + 82: 'r', + 83: 's', + 84: 't', + 85: 'u', + 86: 'v', + 87: 'w', + 88: 'x', + 89: 'y', + 90: 'z', + 91: 'Left Windows Key / Left ⌘', + 92: 'Right Windows Key', + 93: 'Windows Menu / Right ⌘', + 96: 'numpad 0', + 97: 'numpad 1', + 98: 'numpad 2', + 99: 'numpad 3', + 100: 'numpad 4', + 101: 'numpad 5', + 102: 'numpad 6', + 103: 'numpad 7', + 104: 'numpad 8', + 105: 'numpad 9', + 106: 'multiply', + 107: 'add', + 109: 'subtract', + 110: 'decimal point', + 111: 'divide', + 112: 'f1', + 113: 'f2', + 114: 'f3', + 115: 'f4', + 116: 'f5', + 117: 'f6', + 118: 'f7', + 119: 'f8', + 120: 'f9', + 121: 'f10', + 122: 'f11', + 123: 'f12', + 124: 'f13', + 125: 'f14', + 126: 'f15', + 127: 'f16', + 128: 'f17', + 129: 'f18', + 130: 'f19', + 131: 'f20', + 132: 'f21', + 133: 'f22', + 134: 'f23', + 135: 'f24', + 144: 'num lock', + 145: 'scroll lock', + 186: ';', + 187: '=', + 188: ',', + 189: '‐', + 190: '.', + 191: '?', + 192: '`', + 219: '[', + 220: '\', + 221: ']', + 222: ''', +}; diff --git a/js/bootstrap-3.0.3.min.js b/js/bootstrap-3.0.3.min.js new file mode 100644 index 00000000..1a6258ef --- /dev/null +++ b/js/bootstrap-3.0.3.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.0.3 (http://getbootstrap.com) + * Copyright 2013 Twitter, Inc. + * Licensed under http://www.apache.org/licenses/LICENSE-2.0 + */ + +if("undefined"==typeof jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]}}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){"loadingText"==a?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]'),b=!0;if(a.length){var c=this.$element.find("input");"radio"===c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?b=!1:a.find(".active").removeClass("active")),b&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}b&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition.end&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}this.sliding=!0,f&&this.pause();var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});if(!e.hasClass("active")){if(this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(j),j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(600)}else{if(this.$element.trigger(j),j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")}return f&&this.cycle(),this}};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?(this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350),void 0):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(c).is("body")?a(window):a(c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#\w/.test(e)&&a(e);return f&&f.length&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parents(".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top()),"function"==typeof h&&(h=f.bottom());var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;this.affixed!==i&&(this.unpin&&this.$element.css("top",""),this.affixed=i,this.unpin="bottom"==i?e.top-d:null,this.$element.removeClass(b.RESET).addClass("affix"+(i?"-"+i:"")),"bottom"==i&&this.$element.offset({top:document.body.offsetHeight-h-this.$element.height()}))}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery); \ No newline at end of file diff --git a/js/highlight.pack.js b/js/highlight.pack.js new file mode 100644 index 00000000..763f9c55 --- /dev/null +++ b/js/highlight.pack.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.13.1 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=M.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function c(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function u(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"===e.event?o:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function l(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):B(a.k).forEach(function(e){c(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.endSameAsBegin&&(a.e=a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return s("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var u=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=u.length?t(u.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e){return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}function c(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=o(n.c[t].bR.exec(e)[0])),n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function s(e,n){return!a&&r(n.iR,e)}function p(e,n){var t=R.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function d(e,n,t,r){var a=r?"":j.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=p(E,r),e?(M+=e[1],a+=d(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function b(){var e="string"==typeof E.sL;if(e&&!L[E.sL])return n(k);var t=e?f(E.sL,k,!0,B[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(B[E.sL]=t.top),d(t.language,t.value,!1,!0)}function v(){y+=null!=E.sL?b():h(),k=""}function m(e){y+=e.cN?d(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function N(e,n){if(k+=e,null==n)return v(),0;var t=c(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),v(),t.rB||t.eB||(k=n)),m(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),v(),a.eE&&(k=n));do E.cN&&(y+=I),E.skip||E.sL||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),m(r.starts,"")),a.rE?0:n.length}if(s(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var R=w(e);if(!R)throw new Error('Unknown language: "'+e+'"');l(R);var x,E=i||R,B={},y="";for(x=E;x!==R;x=x.parent)x.cN&&(y=d(x.cN,"",!0)+y);var k="",M=0;try{for(var C,A,S=0;;){if(E.t.lastIndex=S,C=E.t.exec(t),!C)break;A=N(t.substring(S,C.index),C[0]),S=C.index+A}for(N(t.substr(S)),x=E;x.parent;x=x.parent)x.cN&&(y+=I);return{r:M,value:y,language:e,top:E}}catch(O){if(O.message&&-1!==O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function g(e,t){t=t||j.languages||B(L);var r={r:0,value:n(e)},a=r;return t.filter(w).filter(x).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return j.tabReplace||j.useBR?e.replace(C,function(e,n){return j.useBR&&"\n"===e?"
":j.tabReplace?n.replace(/\t/g,j.tabReplace):""}):e}function d(e,n,t){var r=n?y[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n,t,r,o,s,l=i(e);a(l)||(j.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=l?f(l,s,!0):g(s),t=c(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=u(t,c(o),s)),r.value=p(r.value),e.innerHTML=r.value,e.className=d(e.className,l,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){j=o(j,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,h)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=L[n]=t(e);r.aliases&&r.aliases.forEach(function(e){y[e]=n})}function R(){return B(L)}function w(e){return e=(e||"").toLowerCase(),L[e]||L[y[e]]}function x(e){var n=w(e);return n&&!n.disableAutodetect}var E=[],B=Object.keys,L={},y={},k=/^(no-?highlight|plain|text)$/i,M=/\blang(?:uage)?-([\w-]+)\b/i,C=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,I="
",j={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=h,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.autoDetection=x,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:a+r+":"},{b:a+'"'+r+'":'},{b:a+"'"+r+"':"}]},c={cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]},l={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,c]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:l.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!"+e.UIR},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:b,k:{literal:b}},e.CNM,l]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:o}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("swift",function(e){var i={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},t={cN:"type",b:"\\b[A-Z][\\wÀ-ʸ']*",r:0},n=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:i,c:[]},a={cN:"string",c:[e.BE,r],v:[{b:/"""/,e:/"""/},{b:/"/,e:/"/}]},o={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0};return r.c=[o],{k:i,c:[a,e.CLCM,n,t,o,{cN:"function",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{b://},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:i,c:["self",o,a,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:i,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{cN:"meta",b:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{bK:"import",e:/$/,c:[e.CLCM,n]}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},o,r,{bK:"class interface",e:/[{;=]/,i:/[^\s:,]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+d+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/\s*[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[o,r,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:i.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"/},t={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php","php3","php4","php5","php6","php7"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[i]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},i,{cN:"keyword",b:/\$this\b/},c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,t,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},t,a]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U|L)?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U|L)?R"\\(',e:'\\)"'},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e,{b:/\(/,e:/\)/,k:c,r:0,c:["self",t.CLCM,t.CBCM,r,s,e]}]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("properties",function(r){var t="[ \\t\\f]*",e="[ \\t\\f]+",s="("+t+"[:=]"+t+"|"+e+")",n="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",c={e:s,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[r.C("^\\s*[!#]","$"),{b:n+s,rB:!0,c:[{cN:"attr",b:n,endsParent:!0,r:0}],starts:c},{b:a+s,rB:!0,r:0,c:[{cN:"meta",b:a,endsParent:!0,r:0}],starts:c},{cN:"attr",r:0,b:a+t+"$"}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("rust",function(e){var t="([ui](8|16|32|64|128|size)|f(32|64))?",r="alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield move default",n="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{aliases:["rs"],k:{keyword:r,literal:"true false Some None Ok Err",built_in:n},l:e.IR+"!?",i:""}]}});hljs.registerLanguage("tex",function(c){var e={cN:"tag",b:/\\/,r:0,c:[{cN:"name",v:[{b:/[a-zA-Zа-яА-я]+[*]?/},{b:/[^a-zA-Zа-яА-я0-9]/}],starts:{eW:!0,r:0,c:[{cN:"string",v:[{b:/\[/,e:/\]/},{b:/\{/,e:/\}/}]},{b:/\s*=\s*/,eW:!0,r:0,c:[{cN:"number",b:/-?\d*\.?\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?/}]}]}}]};return{c:[e,{cN:"formula",c:[e],r:0,v:[{b:/\$\$/,e:/\$\$/},{b:/\$/,e:/\$/}]},c.C("%","$",{r:0})]}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[e.BE,b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[e.BE,b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[e.BE,b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[e.BE,b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[e.BE,c]},{b:/(fr|rf|f)"/,e:/"/,c:[e.BE,c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}}); \ No newline at end of file diff --git a/layers/index.html b/layers/index.html new file mode 100644 index 00000000..2b5bdc0b --- /dev/null +++ b/layers/index.html @@ -0,0 +1,1705 @@ + + + + + + + + + + + + + + Layers - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Layers

+

Layer

+

There are several layer types, which is specified by the ty attribute:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tyLayer TypeDescription
0PrecompositionRenders a Precomposition
1Solid ColorStatic rectangle filling the canvas with a single color
2ImageRenders an Image
3Null (Empty)No contents, only used for parenting
4ShapeHas an array of shapes
5TextRenders text
6AudioPlays some audio
7Video Placeholder
8Image Sequence
9Video
10Image Placeholder
11Guide
12Adjustment
13Camera3D Camera
14Light
15Data
+

Each layer type has its own properties but there are several common properties:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
nmstring +

Name, as seen from editors and the like

+
mnstring +

Match name, used in expressions

+
ddd0-1 integer +

Whether the layer is 3D. Lottie doesn't actually support 3D stuff so this should always be 0

+
hdboolean +

Whether the layer is hidden

+
tyinteger +

Layer type, must be one of the values seen above

+
indinteger +

Layer index for parenting

+
parentinteger +

Parent index for parenting

+
srnumber +

Time Stretch

+
ipnumber +

Frame when the layer becomes visible

+
opnumber +

Frame when the layer becomes invisible

+
stnumber +

Start Time

+
ttMatte Mode +

Matte mode (see mattes)

+
td0-1 integer +

Matte target (see mattes)

+
masksPropertiesarray of Mask +

Masks for the layer

+
efarray of Custom Effect or Drop Shadow Effect or Fill Effect or Gaussian Blur Effect or Set Matte Effect or Pro Levels Effect or Stroke Effect or Tint Effect or Tritone Effect or Radial Wipe or Wavy Effect or Puppet Effect or Spherize Effect or Mesh Warp Effect or Displacement Map Effect or Twirl Effect +

Effects for the layer

+
syarray of Layer Stroke or Drop Shadow or Inner Shadow or Outer Glow or Inner Glow or Bevel Emboss or Satin or Color Overlay or Gradient Overlay +

Layer styles

+
ksTransform +

Layer transform

+
ao0-1 integer +

If 1, The layer will rotate itself to match its animated position path

+
tpinteger +

Index of the layer used as matte, if omitted assume the layer above the current one

+
hasMaskboolean +

Whether the layer has masks applied

+
mbboolean +

Whether motion blur is enabled for the layer

+
bmBlend Mode +

Blend Mode

+
clstring +

CSS class used by the SVG renderer

+
lnstring +

id attribute used by the SVG renderer

+
tgstring +

tag name used by the SVG renderer

+
cpboolean +

This is deprecated in favour of ct

+
ct0-1 integer +

Marks that transforms should be applied before masks

+
+
+

Note that layers that don't have a visual component (Audio layers for example), +won't have a transform and similar.

+

The layer is only visible between its ip and op. +If they match the corresponding attributes in Animation, the layer +will be visible the whole time, otherwise it will become visible at the frame ip +and disappear at op.

+

Parenting

+

Within a list of layers, the ind attribute (if present) must be unique.

+

Layers having a parent attribute matching another layer will inherit their +parent's transform (except for opacity).

+

Basically you need multiply the transform matrix by the parent's transform matrix +to get a child layer's final transform.

+

The flat layer structure and flexible parenting allows more flexibility but it's +different from the more traditional approach of nesting child layers inside the +parent layer (like a folder structure).

+

One of the advantages of flexible parenting is you can have children of the same +layer be intermixed with unrelated layers.

+

In the following example, the star and the ellipse are in separate layers, +but both have the same parent, which moves left and right. +Between the two there's an additional layer with the rectangle.

+

+

+
+
+
+
+ +
+

+

Auto Orient

+

When true, if the transform position is animated, it rotates the layer along the +path the position follows.

+

In the following example there are two arrows animated along the same path, +with no rotation when the position moves towards the right.

+

The transparent one keeps its rotation the same (ao is 0), while the solid one +follows the path (ao is 1).

+

+

+
+
+
+
+ +
+

+

Mattes

+

A matte allows using a layer as a mask for another layer.

+

The way it works is the layer defining the mask has a tt attribute with the +appropriate value. +By defaults it affects the layer on top (the layer before it in the layer list, which has the td attribute), +otherwise check the tp attribute.

+

In this example there's a layer with a rectangle and a star being masked by an ellipse:

+
+ + + + + +
+
+
+
+
+ + +
+

Masks

+

A layer can have an array of masks that clip the contents of the layer to a shape.

+

This is similar to mattes, but there are a few differences.

+

With mattes, you use a layer to define the clipping area, while with masks +you use an animated bezier curve.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
nmstring +

Name, as seen from editors and the like

+
mnstring +

Match name, used in expressions

+
invboolean +

Inverted

+
ptAnimated Bezier +

Shape

+
oAnimated number +

Opacity

+
modeMask Mode +

Mode

+
xAnimated number +

Expand

+
+
+
+ + + + + + + + + + + + + + + + + +
100
0
+
+
+
+
+ + +
+

Shape Layer

+

Renders vector data.

+

The only special property for this layer is shapes, an array of shapes.

+
+

Also has the attributes from Visual Layer.

+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 4 +

Layer type

+
shapesShape List +

Shapes

+
+
+

Precomposition Layer

+

This layer renders a precomposition.

+

You can find more details in the Precompositions page.

+
+

Also has the attributes from Visual Layer.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 0 +

Layer type

+
refIdstring +

ID of the precomp as specified in the assets

+
winteger +

Width of the clipping rect

+
hinteger +

Height of the clipping rect

+
tmAnimated number +

Time Remapping

+
+
+

Time remapping

+

The tm property maps the time in seconds of the precomposition to show.

+

Basically you get the value of tm at the current frame, then assume that's +a time in seconds since the start of the animation, and render the corresponding +frame of the precomposition.

+

Follows an example of this, here there are two layers showing the same +precomposition, the one at the top right keeps the original time while the bottom +one remaps time as follows:

+
    +
  • frame 0 (0s) maps to 0s (frame 0) in the precomp
  • +
  • frame 30 (0.5s) maps to 3s (frame 180) in the precomp
  • +
  • frame 60 (1s) maps to 1.5s (frame 90) in the precomp
  • +
  • frame 180 (3s) maps to 3s (frame 180) in the precomp
  • +
+

Basically it makes the precomp play in the first half second, then rewind +to half way for the next half second, and plays back to the end for the remaining +2 seconds.

+
+
+
+
+
+
+ + +
+

Null Layer

+

This layer doesn't have any special properties.

+

It's often used by animators as a parent to multiple other layers (see parenting).

+
+

Also has the attributes from Visual Layer.

+ + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 3 +

Layer type

+
+
+

Text Layer

+

For text data, please refer to the section about text for details.

+
+

Also has the attributes from Visual Layer.

+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 5 +

Layer type

+
tText Data +

Data

+
+
+

Image Layer

+

This layer renders a static image.

+
+

Also has the attributes from Visual Layer.

+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 2 +

Layer type

+
refIdstring +

ID of the image as specified in the assets

+
+
+

Solid Color Layer

+

This layer represents a rectangle with a single color.

+

Anything you can do with solid layers, you can do better with a shape layer +and a rectangle shape since none of this layer's own properties can be animated.

+

Note that the color is represented as a string, unlike most other places.

+
+

Also has the attributes from Visual Layer.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 1 +

Layer type

+
scstring +

Color of the layer, unlike most other places, the color is a #rrggbb hex string

+
shnumber +

Height

+
swnumber +

Width

+
+
+
+ + + + + + + + + + + + + +
512
512
+
+
+
+
+ + +
+

Audio Layer

+

This layer plays a sound.

+
+

Also has the attributes from Layer.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 6 +

Layer type

+
auAudio Settings +

Audio Settings

+
refIdstring +

ID of the sound as specified in the assets

+
+
+

Audio Settings

+
+ + + + + + + + + + + + + + + +
AttributeTypeDescription
lvAnimated Vector +

Level

+
+
+

3D Layers

+

Layers can have 3D transforms as well:

+

+

+
+
+
+
+ +
+

+

3D layers need to have the ddd set to 1 (and so does the top-level object).

+

Their transform will habe a and p specified as 3D components.

+

Rotation will be split into 3 properties: rx, ry, rz, and +you have and additional orientation property or.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Anchor
0
0
0
Position
256
256
0
Rotation
0
30
0
Orientation
0
0
0
Scale
100
100
100
+
+
+
+
+ + +
+

Camera Layer

+

Camera for 3D layers.

+
+

Also has the attributes from Layer.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 13 +

Layer type

+
ksTransform +

Layer transform

+
peAnimated number +

Distance from the Z=0 plane. +Small values yield a higher perspective effect.

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
256
Position
0
0
-10
Rotation
0
0
0
Orientation
0
0
0
+
+
+
+
+ + +
+

3D Parenting

+

As with 2D layers, you can parent 3D layers.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Position
0
0
-10
Rotation
0
0
0
Orientation
0
0
0
+
+
+
+
+ + +
+

Data Layer

+

This layer links to a data source.

+
+

Also has the attributes from Layer.

+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
tyinteger = 15 +

Layer type

+
refIdstring +

ID of the data source in assets

+
+
+
+
+ + +
+ + + +
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/playground/builder/index.html b/playground/builder/index.html new file mode 100644 index 00000000..bfd94266 --- /dev/null +++ b/playground/builder/index.html @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + Builder - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + +
+
+
+
    +
  • +
  • +
  • +
  • +
  • +
+
+
+ + +
+
+
+ +
+ + +
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/playground/explain/index.html b/playground/explain/index.html new file mode 100644 index 00000000..d59b306b --- /dev/null +++ b/playground/explain/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/playground/json_editor/index.html b/playground/json_editor/index.html new file mode 100644 index 00000000..c862f474 --- /dev/null +++ b/playground/json_editor/index.html @@ -0,0 +1,1013 @@ + + + + + + + + + + + + + + JSON Editor - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +

+ + + + + + + + + +
+ + +
+ + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/rendering/index.html b/rendering/index.html new file mode 100644 index 00000000..f53cc9ba --- /dev/null +++ b/rendering/index.html @@ -0,0 +1,4878 @@ + + + + + + + + + + + + + + Tips for rendering - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +

Tips for rendering

+ + + + +

Introduction

+

This page will give tips and example code on how to render certain objects within lottie.

+

Lottie has several implementations and some things might vary from player to player, +this guide tries to follow the behaviour of lottie web +which is the reference implementation.

+

For shapes, it ensures the stroke order is the same as in lottie web, which is crucial +for Trim Path to work correctly.

+

All shapes have the d attribute that if has the value 3 the path should be reversed.

+

Code

+

The code examples take some shortcuts for readablility: +all animated properties are shown as static, of course you'd need to get the +correct values to render shapes at a given frame.

+

When adding points to a bezier, there are calls to bezier.add_vertex(). +Assume the in/out tangents are [0, 0] if not specified. +When they are specified they show as set_out_tangent immediately following +the corresponding add_vertex.

+

Bezier tangents are assumed to be relative to their vertex since that's how lottie works +but it might be useful to keep them as absolute points when rendering.

+

All the examples show the original on the left and the bezier on the right.

+

Explanation for bezier operations is outside the scope of this guide, +the code below use a simple bezier library for some operations, +you can check its sources +for some context on what the various functions do.

+

Rectangle

+

See Rectangle.

+

Note that unlike other shapes, on lottie web when the d attribute is missing, +the rectangle defaults as being reversed.

+

Rectangle without rounded corners:

+
+ + + + + + + + + + + + + + + + + +
256
256
256
256
+
+
+
+
+
+ +
function rect(position, size)
+{
+    let left = position[0] - size[0] / 2;
+    let right = position[0] + size[0] / 2;
+    let top = position[1] - size[1] / 2;
+    let bottom = position[1] + size[1] / 2;
+
+    let bezier = new Bezier();
+
+    bezier.add_vertex(right, top);
+    bezier.add_vertex(right, bottom);
+    bezier.add_vertex(left, bottom);
+    bezier.add_vertex(left, top);
+
+    return bezier;
+}
+
+// Example invocation
+rect(shape.p.k, shape.s.k);
+
+ +
+

+

With rounded corners:

+
+ + + + + + + + + + + + + + + + + + + + + +
256
256
256
256
50
+
+
+
+
+
+ +
function rounded_rect(position, size, roundness)
+{
+    let left = position[0] - size[0] / 2;
+    let right = position[0] + size[0] / 2;
+    let top = position[1] - size[1] / 2;
+    let bottom = position[1] + size[1] / 2;
+
+    let rounded = Math.min(size[0] / 2, size[1] / 2, roundness);
+
+    let bezier = new Bezier();
+
+    // top right, going down
+    bezier.add_vertex(right, top + rounded)
+        .set_in_tangent(0, -rounded/2);
+
+    // bottom right
+    bezier.add_vertex(right, bottom - rounded)
+        .set_out_tangent(0, rounded/2);
+
+    bezier.add_vertex(right - rounded, bottom)
+        .set_in_tangent(rounded/2, 0);
+
+    // bottom left
+    bezier.add_vertex(left + rounded, bottom)
+        .set_out_tangent(-rounded/2, 0);
+
+    bezier.add_vertex(left, bottom - rounded)
+        .set_in_tangent(0, rounded/2);
+
+    // top left
+    bezier.add_vertex(left, top + rounded)
+        .set_out_tangent(0, -rounded/2);
+
+    bezier.add_vertex(left + rounded, top)
+        .set_in_tangent(-rounded/2, 0);
+
+
+    // back to top right
+    bezier.add_vertex(right - rounded, top)
+        .set_out_tangent(rounded/2, 0);
+
+    return bezier;
+}
+
+// Example invocation
+rounded_rect(shape.p.k, shape.s.k, shape.r.k);
+
+ +
+

+

Ellipse

+

See Ellipse.

+

The stroke direction should start at the top. +If you think of the ellipse as a clock, start at 12 go clockwise.

+

The magic number 0.5519 is what lottie uses for this, based on this article.

+
+ + + + + + + + + + + + + + + + + +
256
256
256
256
+
+
+
+
+
+ +
function ellipse(position, size)
+{
+    const ellipse_constant = 0.5519;
+
+    let x = position[0];
+    let y = position[1];
+    let radius_x = size[0] / 2;
+    let radius_y = size[1] / 2;
+    let tangent_x = radius_x * ellipse_constant;
+    let tangent_y = radius_y * ellipse_constant;
+
+    let bezier = new Bezier();
+
+    bezier.add_vertex(x, y - radius_y)
+        .set_in_tangent(-tangent_x, 0)
+        .set_out_tangent(tangent_x, 0);
+
+    bezier.add_vertex(x + radius_x, y)
+        .set_in_tangent(0, -tangent_y)
+        .set_out_tangent(0, tangent_y);
+
+    bezier.add_vertex(x, y + radius_y)
+        .set_in_tangent(tangent_x, 0)
+        .set_out_tangent(-tangent_x, 0);
+
+    bezier.add_vertex(x - radius_x, y)
+        .set_in_tangent(0, tangent_y)
+        .set_out_tangent(0, -tangent_y);
+
+    return bezier;
+}
+
+// Example invocation
+ellipse(shape.p.k, shape.s.k);
+
+ +
+

+

PolyStar

+

Pseudocode for rendering a PolyStar.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
5
0
200
100
0
0
+
+
+
+
+
+ +
function polystar(
+    position,
+    type,
+    points,
+    rotation,
+    outer_radius,
+    outer_roundness,
+    inner_radius,
+    inner_roundness
+)
+{
+    let result = new Bezier();
+
+    let half_angle = Math.PI / points;
+    let angle_radians = rotation / 180 * Math.PI
+
+    // Tangents for rounded courners
+    let tangent_len_outer = outer_roundness * outer_radius * 2 * Math.PI / (points * 4 * 100);
+    let tangent_len_inner = inner_roundness * inner_radius * 2 * Math.PI / (points * 4 * 100);
+
+    for ( let i = 0; i < points; i++ )
+    {
+        let main_angle = -Math.PI / 2 + angle_radians + i * half_angle * 2;
+
+        let outer_vertex = new Point(
+            outer_radius * Math.cos(main_angle),
+            outer_radius * Math.sin(main_angle)
+        );
+
+        let outer_tangent = new Point(0, 0);
+        if ( outer_radius != 0 )
+            outer_tangent = new Point(
+                outer_vertex.y / outer_radius * tangent_len_outer,
+                -outer_vertex.x / outer_radius * tangent_len_outer
+            );
+
+        result.add_vertex(position.add(outer_vertex))
+            .set_in_tangent(outer_tangent)
+            .set_out_tangent(outer_tangent.neg());
+
+        // Star inner radius
+        if ( type == 1 )
+        {
+            let inner_vertex = new Point(
+                inner_radius * Math.cos(main_angle + half_angle),
+                inner_radius * Math.sin(main_angle + half_angle)
+            );
+
+            let inner_tangent = new Point(0, 0);
+            if ( inner_radius != 0 )
+                inner_tangent = new Point(
+                    inner_vertex.y / inner_radius * tangent_len_inner,
+                    -inner_vertex.x / inner_radius * tangent_len_inner
+                );
+
+            result.add_vertex(position.add(inner_vertex))
+                .set_in_tangent(inner_tangent)
+                .set_out_tangent(inner_tangent.neg());
+        }
+    }
+
+    return result;
+}
+
+// Example invocation
+polystar(new Point(shape.p.k), shape.sy, shape.pt.k, shape.r.k, shape.or.k, shape.os.k, shape.ir?.k, shape.is?.k);
+
+ +
+

+

Pucker Bloat

+

See Pucker / Bloat.

+
+ + + + + +
50
+
+
+
+
+
+ +
function pucker_bloat(
+    // Beziers as collected from the other shapes
+    collected_shapes,
+    // "a" property from the Pucker/Bloat modifier
+    amount
+)
+{
+    // Normalize to [0, 1]
+    amount /= 100;
+
+    // Find the mean of the bezier vertices
+    let center = new Point(0, 0);
+    let number_of_vertices = 0;
+    for ( let input_bezier of collected_shapes )
+    {
+        for ( let point of input_bezier.points )
+        {
+            center.x += point.pos.x;
+            center.y += point.pos.y;
+            number_of_vertices += 1;
+        }
+    }
+
+    center.x /= number_of_vertices;
+    center.y /= number_of_vertices;
+
+    let result = [];
+
+    for ( let input_bezier of collected_shapes )
+    {
+        let output_bezier = new Bezier();
+        for ( let point of input_bezier.points )
+        {
+            // Here we convert tangents to global coordinates
+            let vertex = lerp(point.pos, center, amount);
+            let in_tangent = lerp(point.in_tangent.add(point.pos), center, -amount).sub(vertex);
+
+            let out_tangent = lerp(point.out_tangent.add(point.pos), center, -amount).sub(vertex);
+            output_bezier.add_vertex(vertex)
+                .set_in_tangent(in_tangent)
+                .set_out_tangent(out_tangent);
+        }
+
+        output_bezier.closed = input_bezier.closed;
+
+        result.push(output_bezier);
+    }
+
+    return result;
+}
+
+// Example invocation
+pucker_bloat([convert_shape(star)], modifier.a.k);
+
+ +
+

+

Rounded Corners

+

See Rounded Corners.

+

It approximates rounding using circular arcs.

+

The magic number 0.5519 is what lottie uses for this, based on this article.

+
+ + + + + +
50
+
+
+
+
+
+ +
// Helper function to perform rounding on a single vertex
+function get_vertex_tangent(
+    // Bezier to round
+    bezier,
+    // Vertex in the bezier we are rounding
+    current_vertex,
+    // Index of the next point along the curve
+    closest_index,
+    // Rounding radius
+    round_distance
+)
+{
+    const tangent_length = 0.5519;
+
+    // closest_index module bezier.length
+    closest_index = closest_index % bezier.points.length;
+    if ( closest_index < 0 )
+        closest_index += bezier.points.length;
+
+
+    let closest_vertex = bezier.points[closest_index].pos;
+    let distance = current_vertex.distance(closest_vertex);
+    let new_pos_perc = distance != 0 ? Math.min(distance/2, round_distance) / distance : 0;
+    let vertex = closest_vertex.sub(current_vertex).mul(new_pos_perc).add(current_vertex);
+    let tangent = vertex.sub(current_vertex).neg().mul(tangent_length);
+    return [vertex, tangent];
+}
+
+// Rounding for a single continuos curve
+function round_bezier_corners(
+    // Bezier to round
+    original,
+    // Rounding radius
+    round_distance
+)
+{
+    let result = new Bezier()
+    result.closed = original.closed;
+
+    for ( let i = 0; i < original.points.length; i++ )
+    {
+        let point = original.points[i];
+
+        // Start and end of a non-closed path don't get rounded
+        if ( !original.closed && (i == 0 || i == original.points.length - 1) )
+        {
+            result.add_vertex(point.pos)
+                .set_in_tangent(point.in_tangent)
+                .set_out_tangent(point.out_tangent);
+        }
+        else
+        {
+            let [vert1, out_t] = get_vertex_tangent(original, point.pos, i - 1, round_distance);
+            result.add_vertex(vert1)
+                .set_out_tangent(out_t);
+
+            let [vert2, in_t] = get_vertex_tangent(original, point.pos, i + 1, round_distance);
+            result.add_vertex(vert2)
+                .set_in_tangent(in_t);
+        }
+    }
+
+    return result;
+}
+
+// Rounding on multiple bezier
+function round_corners(
+    // Beziers as collected from the other shapes
+    collected_shapes,
+    // "r" property from lottie
+    r
+)
+{
+    let result = []
+
+    for ( let input_bezier of collected_shapes )
+        result.push(round_bezier_corners(input_bezier, r));
+
+    return result;
+}
+
+// Example invocation
+round_corners([convert_shape(star)], modifier.r.k);
+
+ +
+

+

Zig Zag

+

See Zig Zag.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Zig Zag
10
10
Star
0
0
5
3
+
+
+
+
+
+ +

+function angle_mean(a, b)
+{
+    if ( Math.abs(a-b) > Math.PI )
+        return (a + b) / 2 + Math.PI;
+
+    return (a + b) / 2;
+}
+
+function zig_zag_corner(output_bezier, segment_before, segment_after, amplitude, direction, tangent_length)
+{
+    let point;
+    let angle;
+    let tan_angle;
+
+    // We use 0.01 and 0.99 instead of 0 and 1 because they yield better results
+    if ( !segment_before )
+    {
+        point = segment_after.points[0];
+        angle = segment_after.normal_angle(0.01);
+        tan_angle = segment_after.tangent_angle(0.01);
+    }
+    else if ( !segment_after )
+    {
+        point = segment_before.points[3];
+        angle = segment_before.normal_angle(0.99);
+        tan_angle = segment_before.tangent_angle(0.99);
+    }
+    else
+    {
+        point = segment_after.points[0];
+        angle = angle_mean(segment_after.normal_angle(0.01), segment_before.normal_angle(0.99));
+        tan_angle = angle_mean(segment_after.tangent_angle(0.01), segment_before.tangent_angle(0.99));
+    }
+
+    let vertex = output_bezier.add_vertex(point.add_polar(angle, direction * amplitude));
+    if ( tangent_length !== 0 )
+    {
+        vertex.set_in_tangent(Point.polar(tan_angle, -tangent_length));
+        vertex.set_out_tangent(Point.polar(tan_angle, tangent_length));
+    }
+}
+
+function zig_zag_segment(output_bezier, segment, amplitude, frequency, direction, tangent_length)
+{
+    for ( let i = 0; i < frequency; i++ )
+    {
+        let f = (i + 1) / (frequency + 1);
+        let t = segment.t_at_length_percent(f);
+        let angle = segment.normal_angle(t);
+        let point = segment.point(t);
+
+        let vertex = output_bezier.add_vertex(point.add_polar(angle, direction * amplitude));
+        if ( tangent_length !== 0 )
+        {
+            let tan_angle = segment.tangent_angle(t);
+            vertex.set_in_tangent(Point.polar(tan_angle, -tangent_length));
+            vertex.set_out_tangent(Point.polar(tan_angle, tangent_length));
+        }
+
+        direction = -direction;
+    }
+
+    return direction;
+}
+
+function zig_zag_bezier(input_bezier, amplitude, frequency, smooth)
+{
+    let output_bezier = new Bezier();
+
+    output_bezier.closed = input_bezier.closed;
+    let count = input_bezier.segment_count();
+
+    if ( count == 0 )
+        return output_bezier;
+
+    let direction = -1;
+    let segment = input_bezier.closed ? input_bezier.segment(count - 1) : null;
+    let next_segment = input_bezier.segment(0);
+
+    next_segment.calculate_length_data();
+    let tangent_length = smooth ? next_segment.length / (frequency + 1) / 2 : 0;
+
+    zig_zag_corner(output_bezier, segment, next_segment, amplitude, -1, tangent_length);
+
+    for ( let i = 0; i < count; i++ )
+    {
+        segment = next_segment;
+
+        direction = zig_zag_segment(output_bezier, segment, amplitude, frequency, -direction, tangent_length);
+
+        if ( i == count - 1 && !input_bezier.closed )
+            next_segment = null;
+        else
+            next_segment = input_bezier.segment((i + 1) % count);
+
+        zig_zag_corner(output_bezier, segment, next_segment, amplitude, direction, tangent_length);
+    }
+
+    return output_bezier;
+}
+
+function zig_zag(
+    // Beziers as collected from the other shapes
+    collected_shapes,
+    amplitude,
+    frequency,
+    point_type
+)
+{
+    // Ensure we have an integer number of segments
+    frequency = Math.max(0, Math.round(frequency));
+
+    let result = [];
+
+    for ( let input_bezier of collected_shapes )
+        result.push(zig_zag_bezier(input_bezier, amplitude, frequency, point_type === 2));
+
+    return result;
+}
+
+// Example invocation
+zig_zag([convert_shape(star)], modifier.s.k, modifier.r.k, modifier.pt.k);
+
+ +
+

+

Offset Path

+

See Offset Path.

+
+ + + + + + + + + + + + + + + + + + + + + + + +
Offset Path
10
100
Star
0
+
+
+
+
+
+ +
/*
+    Simple offset of a linear segment
+*/
+function linear_offset(p1, p2, amount)
+{
+    let angle = Math.atan2(p2.x - p1.x, p2.y - p1.y);
+    return [
+        p1.add_polar(angle, amount),
+        p2.add_polar(angle, amount)
+    ];
+}
+
+/*
+    Offset a bezier segment
+    only works well if the segment is flat enough
+*/
+function offset_segment(segment, amount)
+{
+    let [p0, p1a] = linear_offset(segment.points[0], segment.points[1], amount);
+    let [p1b, p2b] = linear_offset(segment.points[1], segment.points[2], amount);
+    let [p2a, p3] = linear_offset(segment.points[2], segment.points[3], amount);
+    let p1 = line_intersection(p0, p1a, p1b, p2b) ?? p1a;
+    let p2 = line_intersection(p2a, p3, p1b, p2b) ?? p2a;
+
+    return new BezierSegment(p0, p1, p2, p3);
+}
+
+/*
+    Join two segments
+*/
+function join_lines(output_bezier, seg1, seg2, line_join, miter_limit)
+{
+    let p0 = seg1.points[3];
+    let p1 = seg2.points[0];
+
+    // Bevel
+    if ( line_join == 3 )
+        return p0;
+
+
+    // Connected, they don't need a joint
+    if ( p0.is_equal(p1) )
+        return p0;
+
+    let last_point = output_bezier.points[output_bezier.points.length - 1];
+
+    // Round
+    if ( line_join == 2 )
+    {
+        const ellipse_constant = 0.5519;
+        let angle_out = seg1.tangent_angle(1);
+        let angle_in = seg2.tangent_angle(0) + Math.PI;
+        let center = line_intersection(
+            p0, p0.add_polar(angle_out + Math.PI / 2, 100),
+            p1, p1.add_polar(angle_out + Math.PI / 2, 100)
+        );
+        let radius = center ? center.distance(p0) : p0.distance(p1) / 2;
+        last_point.set_out_tangent(Point.polar(angle_out, 2 * radius * ellipse_constant));
+
+        output_bezier.add_vertex(p1)
+            .set_in_tangent(Point.polar(angle_in, 2 * radius * ellipse_constant));
+
+        return p1;
+    }
+
+    // Miter
+    let t0 = p0.is_equal(seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+    let t1 = p1.is_equal(seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+    let intersection = line_intersection(t0, p0, p1, t1);
+    if ( intersection && intersection.distance(p0) < miter_limit )
+    {
+        output_bezier.add_vertex(intersection);
+        return intersection;
+    }
+
+    return p0;
+}
+
+
+function get_intersection(a, b)
+{
+    let intersect = a.intersections(b);
+
+    if ( intersect.length && fuzzy_compare(intersect[0], 1) )
+        intersect.shift();
+
+    if ( intersect.length )
+        return intersect[0];
+
+    return null;
+}
+
+function prune_segment_intersection(a, b)
+{
+    let out_a = [...a];
+    let out_b = [...b];
+
+    let intersect = get_intersection(a[a.length-1], b[0]);
+
+    if ( intersect )
+    {
+        out_a[a.length-1] = a[a.length-1].split(intersect[0])[0];
+        out_b[0] = b[0].split(intersect[1])[1];
+    }
+
+    if ( a.length > 1 && b.length > 1 )
+    {
+        intersect = get_intersection(a[0], b[b.length - 1]);
+
+        if ( intersect )
+        {
+            return [
+                [a[0].split(intersect[0])[0]],
+                [b[b.length-1].split(intersect[1])[1]],
+            ];
+        }
+    }
+
+    return [out_a, out_b];
+}
+
+function prune_intersections(segments)
+{
+    for ( let i = 1; i < segments.length; i++ )
+    {
+        [segments[i-1], segments[i]] = prune_segment_intersection(segments[i - 1], segments[i]);
+    }
+
+    if ( segments.length > 1 )
+        [segments[segments.length - 1], segments[0]] = prune_segment_intersection(segments[segments.length - 1], segments[0]);
+
+    return segments;
+}
+
+function offset_segment_split(segment, amount)
+{
+    /*
+        We split each bezier segment into smaller pieces based
+        on inflection points, this ensures the control point
+        polygon is convex.
+
+        (A cubic bezier can have none, one, or two inflection points)
+    */
+    let flex = segment.inflection_points();
+
+    if ( flex.length == 0 )
+    {
+        return [offset_segment(segment, amount)];
+    }
+    else if ( flex.length == 1 || flex[1] == 1 )
+    {
+        let [left, right] = segment.split(flex[0]);
+
+        return [
+            offset_segment(left, amount),
+            offset_segment(right, amount)
+        ];
+    }
+    else
+    {
+        let [left, mid_right] = segment.split(flex[0]);
+        let t = (flex[1] - flex[0]) / (1 - flex[0]);
+        let [mid, right] = mid_right.split(t);
+
+        return [
+            offset_segment(left, amount),
+            offset_segment(mid, amount),
+            offset_segment(right, amount)
+        ];
+    }
+
+}
+
+function offset_path(
+    // Beziers as collected from the other shapes
+    collected_shapes,
+    amount,
+    line_join,
+    miter_limit,
+)
+{
+    let result = [];
+
+    for ( let input_bezier of collected_shapes )
+    {
+        let output_bezier = new Bezier();
+
+        output_bezier.closed = input_bezier.closed;
+        let count = input_bezier.segment_count();
+
+        let multi_segments = [];
+
+        for ( let i = 0; i < count; i++ )
+            multi_segments.push(offset_segment_split(input_bezier.segment(i), amount));
+
+        // Open paths are stroked rather than being simply offset
+        if ( !input_bezier.closed )
+        {
+            for ( let i = count - 1; i >= 0; i-- )
+                multi_segments.push(offset_segment_split(input_bezier.inverted_segment(i), amount));
+        }
+
+        multi_segments = prune_intersections(multi_segments);
+
+        // Add bezier segments to the output and apply line joints
+        let last_point = null;
+        let last_seg = null;
+
+        for ( let multi_segment of multi_segments )
+        {
+            if ( last_seg )
+                last_point = join_lines(output_bezier, last_seg, multi_segment[0], line_join, miter_limit);
+
+            last_seg = multi_segment[multi_segment.length - 1];
+
+            for ( let segment of multi_segment )
+            {
+                if ( segment.points[0].is_equal(last_point) )
+                {
+                    output_bezier.points[output_bezier.points.length - 1]
+                        .set_out_tangent(segment.points[1].sub(segment.points[0]));
+                }
+                else
+                {
+                    output_bezier.add_vertex(segment.points[0])
+                        .set_out_tangent(segment.points[1].sub(segment.points[0]));
+                }
+
+
+                output_bezier.add_vertex(segment.points[3])
+                    .set_in_tangent(segment.points[2].sub(segment.points[3]));
+
+                last_point = segment.points[3];
+            }
+        }
+
+        if ( multi_segments.length )
+            join_lines(output_bezier, last_seg, multi_segments[0][0], line_join, miter_limit);
+
+        result.push(output_bezier);
+    }
+
+    return result;
+}
+
+// Example invocation
+offset_path([convert_shape(star)], modifier.a.k, modifier.lj, modifier.ml.k);
+
+ +
+

+

Trim Path

+
+ + + + + + + + + + + + + + + + + +
0
50
0
+
+
+
+
+
+ +

+function trim_path_gather_chunks(collected_shapes, multiple)
+{
+    let chunks = [];
+
+    // Shapes are handled as a single unit
+    if ( multiple === 2 )
+        chunks.push({segments: [], length: 0});
+
+    for ( let input_bezier of collected_shapes )
+    {
+        // Shapes are all affected separately
+        if ( multiple === 1 )
+            chunks.push({segments: [], length: 0});
+
+        let chunk = chunks[chunks.length-1];
+
+        for ( let i = 0; i < input_bezier.segment_count(); i++ )
+        {
+            let segment = input_bezier.segment(i);
+            let length = segment.get_length();
+            chunk.segments.push(segment);
+            chunk.length += length;
+        }
+
+        // Use null as a marker to start a new bezier
+        if ( multiple == 2 )
+            chunk.segments.push(null);
+    }
+
+    return chunks;
+}
+
+function trim_path_chunk(chunk, start, end, output_shapes)
+{
+    // Note: start and end have been normalized and have the offset applied
+    // The offset itself was normalized into [0, 1] so this is always true:
+    // 0 <= start < end <= 2
+
+    // Some offsets require us to handle different "splits"
+    // We want each split to be a pair [s, e] such that
+    // 0 <= s < e <= 1
+    var splits = [];
+
+    if ( end <= 1 )
+    {
+        // Simplest case, the segment is in [0, 1]
+        splits.push([start, end]);
+    }
+    else if ( start > 1 )
+    {
+        // The whole segment is outside [0, 1]
+        splits.push([start-1, end-1]);
+    }
+    else
+    {
+        // The segment goes over the end point, so we need two splits
+        splits.push([start, 1]);
+        splits.push([0, end-1]);
+    }
+
+    // Each split is a separate bezier, all left to do is finding the
+    // bezier segment to add to the output
+    for ( let [s, e] of splits )
+    {
+        let start_length = s * chunk.length;
+        let start_t;
+        let end_length = e * chunk.length;
+        let prev_length = 0;
+
+        let output_bezier = new Bezier(false);
+        output_shapes.push(output_bezier);
+
+        for ( let i = 0; i < chunk.segments.length; i++ )
+        {
+            let segment = chunk.segments[i];
+
+            // New bezier marker found
+            if ( segment === null )
+            {
+                output_bezier = new Bezier(false);
+                output_shapes.push(output_bezier);
+                continue;
+            }
+
+            if ( segment.length >= end_length )
+            {
+                let end_t = segment.t_at_length(end_length);
+
+                if ( segment.length >= start_length )
+                {
+                    start_t = segment.t_at_length(start_length);
+                    segment = segment.split(start_t)[1];
+                    end_t = (end_t - start_t) / (1 - start_t);
+                }
+
+                output_bezier.add_segment(segment.split(end_t)[0], false);
+                break;
+            }
+
+            if ( start_t === undefined )
+            {
+                if ( segment.length >= start_length )
+                {
+                    start_t = segment.t_at_length(start_length);
+                    output_bezier.add_segment(segment.split(start_t)[1], false);
+                }
+            }
+            else
+            {
+                output_bezier.add_segment(segment, true);
+            }
+
+            start_length -= segment.length;
+            end_length -= segment.length;
+        }
+    }
+}
+
+function trim_path(
+    collected_shapes,
+    start,
+    end,
+    offset,
+    multiple
+)
+{
+    // Normalize Inputs
+    offset = offset / 360 % 1;
+    if ( offset < 0 )
+        offset += 1;
+
+    start = Math.min(1, Math.max(0, start / 100));
+    end = Math.min(1, Math.max(0, end / 100));
+
+    if ( end < start )
+        [start, end] = [end, start];
+
+    // Apply offset
+    start += offset;
+    end += offset;
+
+    // Handle the degenerate cases
+    if ( fuzzy_compare(start, end) )
+        return [new Bezier(false)];
+
+    if ( fuzzy_zero(start) && fuzzy_compare(end, 1) )
+        return collected_shapes;
+
+    // Gather up the segments to trim
+    let chunks = trim_path_gather_chunks(collected_shapes, multiple);
+
+    let output_shapes = [];
+
+    for ( let chunk of chunks )
+        trim_path_chunk(chunk, start, end, output_shapes);
+
+    return output_shapes;
+
+}
+
+// Example invocation
+trim_path(shapes, modifier.s.k, modifier.e.k, modifier.o.k, modifier.m);
+
+ +
+

+

Transform

+ + +

This is how to convert a transform object into a matrix.

+

Assuming the matrix

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ac00
bd00
0010
txty01
+

The names a, b, etc are the ones commonly used for CSS transforms.

+

4D matrix to allow for 3D transforms, even though currently lottie only supports 2D graphics.

+

Multiplications are right multiplications (Next = Previous * StepOperation).

+

If your transform is transposed (tx, ty are on the last column), perform left multiplication instead.

+

Perform the following operations on a matrix starting from the identity matrix (or the parent object's transform matrix):

+

Translate by -a:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
1000
0100
0010
-a[0]-a[1]01
+

Scale by s/100:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
s[0]/100000
0s[1]/10000
0010
0001
+

Rotate by -sa (can be skipped if not skewing)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
cos(-sa)sin(-sa)00
-sin(-sa)cos(-sa)00
0010
0001
+

Skew by sk (can be skipped if not skewing)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
1tan(-sk)00
0100
0010
0001
+

Rotate by sa (can be skipped if not skewing)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
cos(sa)sin(sa)00
-sin(sa)cos(sa)00
0010
0001
+

Rotate by -r

+ + + + + + + + + + + + + + + + + + + + + + + + + +
cos(-r)sin(-r)00
-sin(-r)cos(-r)00
0010
0001
+

If you are handling an auto orient layer, +evaluate and apply auto-orient rotation.

+

Translate by p

+ + + + + + + + + + + + + + + + + + + + + + + + + +
1000
0100
0010
p[0]p[1]01
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
256
256
256
256
100
100
0
0
0
100
+
+
+
+
+ + +
+

3D Transform

+

If you have a 3D transform, the process is similar, with a, p, s, +using their 3D matrices, note that for p and a the Z axis is inverted.

+

The rotation step is a bit more complicated, with the 2D rotation being +equivalent to a Z rotation.

+

The rotation step above is replaced with the following set of steps:

+

Rotate by -rz

+ + + + + + + + + + + + + + + + + + + + + + + + + +
cos(-r)sin(-r)00
-sin(-r)cos(-r)00
0010
0001
+

Rotate by ry

+ + + + + + + + + + + + + + + + + + + + + + + + +
cos(r)0sin(r)0
0100
-sin(r)0cos(-r)0
001
+

Rotate by rx

+ + + + + + + + + + + + + + + + + + + + + + + + + +
1000
0cos(r)-sin(r)0
0-sin(r)cos(-r)0
0001
+

Then repeat the steps for or:

+

Rotate by -or[2] (Z axis)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
cos(-r)sin(-r)00
-sin(-r)cos(-r)00
0010
0001
+

Rotate by or[1] (Y axis)

+ + + + + + + + + + + + + + + + + + + + + + + + +
cos(r)0sin(r)0
0100
-sin(r)0cos(-r)0
001
+

Rotate by or[0] (X axis)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
1000
0cos(r)-sin(r)0
0-sin(r)cos(-r)0
0001
+

Auto Orient

+

Auto-orient is only relevant for layers that have ao set to 1 an animated position.

+

You get the derivative of the position property at the current time as a +pair (dx, dy), and find the angle with atan2(dy, dx), then rotate +by that angle clockwise:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
cos(-r)sin(-r)00
-sin(-r)cos(-r)00
0010
0001
+

Animated Properties

+

Assuming a 1D property, a keyframe looks something like this:

+
{
+    "t": start_time,
+    "s": [
+        start_value
+    ],
+    "o": {
+        "x": [
+            ox
+        ],
+        "y": [
+            oy
+        ]
+    },
+    "i": {
+        "x": [
+            ix
+        ],
+        "y": [
+            iy
+        ]
+    }
+}
+
+

Where:

+
    +
  • t is the time at the start of the keyframe (in frames),
  • +
  • s is the value at that time
  • +
  • i and o are the in/out bezier tangents
  • +
+

The transition between keyframes is defined by two keyframes, +for simplicity we'll refer to the named values above plus end_time and +end_value corresponding to t and s on the keyframe after the one listed.

+

The transition is given as a cubic bezier curve whose x axis is time and +the y axis is the interpolating factor between start_value and end_value.

+

The four points of this bezier curve are: (0, 0), (ox, oy), (iy, iy), (1, 1).

+

x is given by x = (current_time - start_time) / (end_time - start_time).

+

If the bezier is defined as

+

a t3 + b t2 + c t + d = 0

+

then you need to find the cubic roots of

+

a t3 + b t2 + c t + d - x = 0

+

to find the t corresponding to that x, (You only need to consider real roots in [0, 1]).

+

Then you can find the y by evaluating the bezier at t.

+

The final value is as follows: lerp(y, start_value, end_value).

+
+
+ + +
+

Effects

+ + + +

Fill Effect

+
+ + + + + + + + + + + + + + + + + + + + +
1
Color
1
0.9
0
+
+
+ +
+
+ +
#version 100
+
+uniform highp vec4 color;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+void main()
+{
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+    highp vec4 pixel = texture2D(texture_sampler, uv);
+
+    gl_FragColor = color;
+    gl_FragColor.a = 1.0;
+    gl_FragColor *= pixel.a * color.a;
+}
+
+ +
+

+

Tritone Effect

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bright
1
1
1
Mid
0.3
0.8
0.3
Dark
0
0
0
+
+
+ +
+
+ +
#version 100
+
+uniform highp vec4 bright;
+uniform highp vec4 mid;
+uniform highp vec4 dark;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+void main()
+{
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+    highp vec4 pixel = texture2D(texture_sampler, uv);
+
+    highp float lightness = sqrt(pixel.r * pixel.r * 0.299 + pixel.g * pixel.g * 0.587 + pixel.b * pixel.b * 0.114);
+    // If you want results more similar to lottie-web use the lightness below
+    // (this shader has a more accurate lightness calculation)
+    // lightness = sqrt((pixel.r * pixel.r + pixel.g * pixel.g + pixel.b * pixel.b) / 3.0);
+
+    if ( lightness < 0.5 )
+    {
+        lightness *= 2.0;
+        gl_FragColor = dark * (1.0 - lightness) + mid * lightness;
+    }
+    else
+    {
+        lightness = (lightness - 0.5) * 2.0;
+        gl_FragColor = mid * (1.0 - lightness) + bright * lightness;
+    }
+
+    gl_FragColor *= pixel.a;
+}
+
+ +
+

+

Gaussian Blur

+

This is a two-pass shader, the uniform pass is has value 0 +on the first pass and value 1 on the second pass.

+
+ + + + + + + + + + + + + +
25
+
+
+ +
+
+ +
#version 300 es
+
+#define PI 3.1415926538
+precision highp float;
+
+uniform float sigma;
+uniform int direction;
+uniform int kernel_size;
+uniform bool wrap;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+uniform int pass;
+
+out vec4 FragColor;
+
+
+vec4 texture_value(vec2 uv)
+{
+    if ( wrap )
+    {
+        if ( uv.x < 0. ) uv.x = 1. - uv.x;
+        if ( uv.x > 1. ) uv.x = uv.x - 1.;
+        if ( uv.y < 0. ) uv.y = 1. - uv.y;
+        if ( uv.y > 1. ) uv.y = uv.y - 1.;
+    }
+    else if ( uv.x < 0. || uv.x > 1. || uv.y < 0. || uv.y > 1. )
+    {
+        return vec4(0.0);
+    }
+
+    return texture(texture_sampler, uv);
+}
+
+
+vec4 blur_pass(float sigma, int kernel_size, vec2 uv, bool horizontal)
+{
+    float side = float(kernel_size / 2);
+
+    vec2 direction_vector = horizontal ?
+        vec2(1.0, 0.0) / canvas_size.x :
+        vec2(0.0, 1.0) / canvas_size.y;
+
+    vec3 delta_gauss;
+    delta_gauss.x = 1.0 / (sqrt(2.0 * PI) * sigma);
+    delta_gauss.y = exp(-0.5 / (sigma * sigma));
+    delta_gauss.z = delta_gauss.y * delta_gauss.y;
+
+    vec4 avg = vec4(0.0, 0.0, 0.0, 0.0);
+    float sum = 0.0;
+
+    vec4 pixel = texture_value(uv);
+    avg += pixel * delta_gauss.x;
+    sum += delta_gauss.x;
+    delta_gauss.xy *= delta_gauss.yz;
+
+    for ( float i = 1.0; i <= side; i++)
+    {
+        for ( float s = -1.0; s <= 1.0; s += 2.0 )
+        {
+            vec2 pos = uv + s * i * direction_vector;
+            pixel = texture_value(pos);
+            avg += pixel * delta_gauss.x;
+        }
+        sum += 2.0 * delta_gauss.x;
+        delta_gauss.xy *= delta_gauss.yz;
+    }
+
+    avg /= sum;
+
+    return avg;
+}
+
+
+void main()
+{
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+
+    int actual_kernel_size = kernel_size == 0 ? int(0.5 + 6.0 * sigma) : kernel_size;
+
+    const float multiplier = 0.25;
+
+    if ( sigma == 0.0 )
+    {
+        FragColor = texture(texture_sampler, uv);
+    }
+    else if ( pass == 0 )
+    {
+        if ( direction != 3 )
+            FragColor = blur_pass(sigma * multiplier, actual_kernel_size, uv, true);
+        else
+            FragColor = texture(texture_sampler, uv);
+    }
+    else if ( pass == 1 )
+    {
+        if ( direction != 2 )
+            FragColor = blur_pass(sigma * multiplier, actual_kernel_size, uv, false);
+        else
+            FragColor = texture(texture_sampler, uv);
+    }
+}
+
+ +
+

+

Drop Shadow Effect

+

The effect below is split into multiple shaders:

+
    +
  • First it generates the shadow
  • +
  • Then it has a 2 pass gaussian blur (simplified from the example above)
  • +
  • Finally, it composites the original image on top of the blurred shadow
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0
0
0
128
135
10
7
+
+
+ +
+
+ +
#version 300 es
+#define PI 3.1415926538
+
+uniform highp vec4 color;
+uniform mediump float angle;
+uniform mediump float distance;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+out highp vec4 FragColor;
+
+void main()
+{
+    // Base pixel value
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+    highp vec4 pixel = texture(texture_sampler, uv);
+
+    // Pixel value at the given offset
+    mediump float radians = -angle * PI / 180.0 + PI / 2.0;
+    highp vec2 shadow_uv = vec2(
+        (gl_FragCoord.x - distance * cos(radians)) / canvas_size.x,
+        1.0 - (gl_FragCoord.y - distance * sin(radians)) / canvas_size.y
+    );
+    highp vec4 shadow_pixel = texture(texture_sampler, shadow_uv);
+
+    // Colorize shadow
+    highp vec4 shadow_color;
+
+    if ( shadow_uv.x >= 0.0 && shadow_uv.x <= 1.0 && shadow_uv.y >= 0.0 && shadow_uv.y <= 1.0 )
+    {
+        shadow_color = color;
+        shadow_color.a = 1.0;
+        shadow_color *= shadow_pixel.a * color.a / 255.0;
+    }
+
+    // Apply shadow below the base pixel
+    FragColor = shadow_color; //pixel * pixel.a + shadow_color * (1.0 - pixel.a);
+}
+
+
#version 300 es
+
+#define PI 3.1415926538
+precision highp float;
+
+uniform float sigma;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+uniform int pass;
+
+out vec4 FragColor;
+
+vec4 blur_pass(float sigma, int kernel_size, vec2 uv, bool horizontal)
+{
+    float side = float(kernel_size / 2);
+
+    vec2 direction_vector = horizontal ?
+        vec2(1.0, 0.0) / canvas_size.x :
+        vec2(0.0, 1.0) / canvas_size.y;
+
+    vec3 delta_gauss;
+    delta_gauss.x = 1.0 / (sqrt(2.0 * PI) * sigma);
+    delta_gauss.y = exp(-0.5 / (sigma * sigma));
+    delta_gauss.z = delta_gauss.y * delta_gauss.y;
+
+    vec4 avg = vec4(0.0, 0.0, 0.0, 0.0);
+    float sum = 0.0;
+
+    vec4 pixel = texture(texture_sampler, uv);
+    avg += pixel * delta_gauss.x;
+    sum += delta_gauss.x;
+    delta_gauss.xy *= delta_gauss.yz;
+
+    for ( float i = 1.0; i <= side; i++)
+    {
+        for ( float s = -1.0; s <= 1.0; s += 2.0 )
+        {
+            vec2 pos = uv + s * i * direction_vector;
+            pixel = texture(texture_sampler, pos);
+            avg += pixel * delta_gauss.x;
+        }
+        sum += 2.0 * delta_gauss.x;
+        delta_gauss.xy *= delta_gauss.yz;
+    }
+
+    avg /= sum;
+
+    return avg;
+}
+
+
+void main()
+{
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+
+    int kernel_size = int(0.5 + 6.0 * sigma);
+
+    const float multiplier = 0.25;
+
+    if ( sigma == 0.0 )
+        FragColor = texture(texture_sampler, uv);
+    else if ( pass == 1 )
+        FragColor = blur_pass(sigma * multiplier, kernel_size, uv, true);
+    else if ( pass == 2 )
+        FragColor = blur_pass(sigma * multiplier, kernel_size, uv, false);
+}
+
+
#version 300 es
+
+precision highp float;
+
+uniform sampler2D original;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+out vec4 FragColor;
+
+vec4 alpha_blend(vec4 top, vec4 bottom)
+{
+    float comp_alpha = bottom.a * (1.0 - top.a);
+    vec4 result;
+    result.a = top.a + comp_alpha;
+    result.rgb = (top.rgb * top.a + bottom.rgb * comp_alpha) / result.a;
+    return result;
+}
+
+void main()
+{
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+
+    FragColor = alpha_blend(
+        texture(original, uv),
+        texture(texture_sampler, vec2(uv.x, 1.0 - uv.y))
+    );
+}
+
+ +
+

+

+

+

Pro Levels Effect

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Composite
0
1
1
0
1
Red
0
1
1
0
1
Green
0
1
1
0
1
Blue
0
1
1
0
1
+
+
+ +
+
+ +
#version 100
+precision highp float;
+
+uniform highp float composite_in_black;
+uniform highp float composite_in_white;
+uniform highp float composite_gamma;
+uniform highp float composite_out_black;
+uniform highp float composite_out_white;
+
+uniform highp float red_in_black;
+uniform highp float red_in_white;
+uniform highp float red_gamma;
+uniform highp float red_out_black;
+uniform highp float red_out_white;
+
+uniform highp float green_in_black;
+uniform highp float green_in_white;
+uniform highp float green_gamma;
+uniform highp float green_out_black;
+uniform highp float green_out_white;
+
+uniform highp float blue_in_black;
+uniform highp float blue_in_white;
+uniform highp float blue_gamma;
+uniform highp float blue_out_black;
+uniform highp float blue_out_white;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+
+float adjust_channel(float value, float in_black, float in_white, float gamma, float out_black, float out_white)
+{
+    float in_delta = in_white - in_black;
+    float out_delta = out_white - out_black;
+    if ( in_delta == 0.0 )
+        return out_black;
+
+    // Clamp to input range
+    if ( value <= in_black && value <= in_white )
+        return out_black;
+
+    if ( value >= in_black && value >= in_white )
+        return out_white;
+
+    // Apply adjustment
+    return out_black + out_delta * pow((value - in_black) / in_delta, 1.0 / gamma);
+}
+
+
+void main()
+{
+    // Base pixel value
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+    highp vec4 pixel = texture2D(texture_sampler, uv);
+
+    // First Pass: composite
+    pixel.rgb = vec3(
+        adjust_channel(pixel.r, composite_in_black, composite_in_white, composite_gamma, composite_out_black, composite_out_white),
+        adjust_channel(pixel.g, composite_in_black, composite_in_white, composite_gamma, composite_out_black, composite_out_white),
+        adjust_channel(pixel.b, composite_in_black, composite_in_white, composite_gamma, composite_out_black, composite_out_white)
+    );
+
+    // Second Pass: individual Channels
+    pixel.rgb = vec3(
+        adjust_channel(pixel.r, red_in_black, red_in_white, red_gamma, red_out_black, red_out_white),
+        adjust_channel(pixel.g, green_in_black, green_in_white, green_gamma, green_out_black, green_out_white),
+        adjust_channel(pixel.b, blue_in_black, blue_in_white, blue_gamma, blue_out_black, blue_out_white)
+    );
+
+    gl_FragColor.rgb = pixel.rgb * pixel.a;
+    gl_FragColor.a = pixel.a;
+}
+
+ +
+

+

Matte3

+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
#version 100
+precision highp float;
+
+uniform int channel;
+uniform int invert;
+uniform int premultiply_mask;
+uniform int show_mask;
+uniform sampler2D mask_layer;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+highp vec3 hsl(vec4 c)
+{
+    float maxc = max(c.r, max(c.g, c.b));
+    float minc = min(c.r, min(c.g, c.b));
+    float h = 0.0;
+    float s = 0.0;
+    float l = (maxc + minc) / 2.0;
+
+    if ( maxc != minc)
+    {
+        float d = maxc - minc;
+        s = l > 0.5 ? d / (2.0 - d) : d / (maxc + minc);
+        if ( maxc == c.r )
+            h = (c.g - c.b) / d + (c.g < c.b ? 6.0 : 0.0);
+        else if ( maxc == c.g )
+            h = (c.b - c.r) / d + 2.0;
+        else if ( maxc == c.b )
+            h = (c.r - c.g) / d + 4.0;
+
+        h /= 6.0;
+    }
+
+    return vec3(h, s, l);
+}
+
+highp float opacity(vec4 pixel, int channel, int invert, int premultiply)
+{
+    if ( premultiply == 1 )
+        pixel *= pixel.a;
+
+    highp float opacity;
+
+    if ( channel == 1 )
+        opacity = pixel.r;
+    else if ( channel == 2 )
+        opacity = pixel.g;
+    else if ( channel == 3 )
+        opacity = pixel.b;
+    else if ( channel == 4 )
+        opacity = pixel.a;
+    else if ( channel == 5 )
+        opacity = sqrt(pixel.r * pixel.r * 0.299 + pixel.g * pixel.g * 0.587 + pixel.b * pixel.b * 0.114);
+    else if ( channel == 6 )
+        opacity = hsl(pixel).x;
+    else if ( channel == 7 )
+        opacity = hsl(pixel).z;
+    else if ( channel == 8 )
+        opacity = hsl(pixel).y;
+    else if ( channel == 9 )
+        opacity = 1.0;
+    else if ( channel == 10 )
+        opacity = 0.0;
+
+
+    return invert == 1 ? 1.0 - opacity : opacity;
+}
+
+vec4 alpha_blend(vec4 top, vec4 bottom)
+{
+    float comp_alpha = bottom.a * (1.0 - top.a);
+    vec4 result;
+    result.a = top.a + comp_alpha;
+    result.rgb = (top.rgb * top.a + bottom.rgb * comp_alpha) / result.a;
+    return result;
+}
+
+void main()
+{
+    // Base pixel value
+    highp vec2 uv = vec2(gl_FragCoord.x / canvas_size.x, gl_FragCoord.y / canvas_size.y);
+    highp vec4 pixel = texture2D(texture_sampler, uv);
+
+    highp vec4 mask = texture2D(mask_layer, uv);
+
+
+    gl_FragColor.a = pixel.a * opacity(mask, channel, invert, premultiply_mask);
+    gl_FragColor.rgb = pixel.rgb * gl_FragColor.a;
+
+    if ( show_mask == 1 )
+        gl_FragColor = alpha_blend(gl_FragColor, mask);
+}
+
+ +
+

+

Bulge

+
+ + + + + + + + + + + + + + + + + + + + + +
286
277
197
179
1.9
+
+
+ +
+
+ +
#version 100
+
+precision highp float;
+
+uniform vec2 center;
+uniform vec2 radius;
+uniform float height;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+vec2 normalize_uv(vec2 coord)
+{
+    return vec2(coord.x / canvas_size.x, coord.y / canvas_size.y);
+}
+
+vec2 exponential_displacement(vec2 uv, float magnitude)
+{
+    return uv * pow(dot(uv, uv), magnitude) - uv;
+}
+
+
+vec2 spherical_displacement(vec2 uv, float magnitude)
+{
+    float radius = (1.0 + magnitude) / (2.0 * sqrt(magnitude));
+
+
+    float arc_ratio = asin(length(uv) / radius) / asin(1.0 / radius);
+    return normalize(uv) * arc_ratio - uv;
+}
+
+vec2 displace(vec2 owo)
+{
+    float t = dot(owo, owo);
+    if (t >= 1.0)
+        return owo;
+
+    float magnitude = abs(height);
+    // We modify the magniture to more closely match AE
+    magnitude = (2.0/(1.0+exp(-3.0*magnitude))-1.0) * (0.23 * magnitude + 0.14);
+    // If the above is too expensive, you can use this instead:
+    // magnitude = magnitude * 0.275;
+    // Both of the above were derived by interpolating sample points
+
+    float sign = height > 0.0 ? 1.0 : -1.0;
+    vec2 displacement =
+        exponential_displacement(owo, magnitude) +
+        spherical_displacement(owo, magnitude)
+    ;
+    return owo + displacement * magnitude * sign;
+
+}
+
+void main()
+{
+    highp vec2 uv = normalize_uv(gl_FragCoord.xy);
+    vec2 norm_center = normalize_uv(center);
+    vec2 norm_radius = normalize_uv(radius);
+
+    // forward transform
+    uv = (uv - norm_center) / norm_radius;
+    //displace
+    uv = displace(uv);
+    // backward transform
+    uv = uv * norm_radius + norm_center;
+
+    gl_FragColor = texture2D(texture_sampler, uv);
+}
+
+ +
+

+

Wave Warp

+

This effect is animated by default, so it has a "time" slider (in seconds).

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
10
40
90
0
1
0
+
+
+ +
+
+ +
#version 100
+
+#define PI 3.1415926538
+#define TAU 6.283185307
+
+precision highp float;
+
+uniform int shape;
+uniform float amplitude;
+uniform float wavelength;
+uniform float angle;
+uniform float speed;
+uniform float phase;
+uniform float time;
+
+uniform mediump vec2 canvas_size;
+uniform sampler2D texture_sampler;
+
+
+vec2 normalize_uv(vec2 coord)
+{
+    return vec2(coord.x / canvas_size.x, coord.y / canvas_size.y);
+}
+
+float clamp_angle(float angle)
+{
+    return mod(angle, TAU);
+}
+
+vec2 project(vec2 a , vec2 b)
+{
+    return dot(a, b) / dot(b, b) * b;
+}
+
+float semicircle(float x)
+{
+    return sqrt(1.0 - pow(clamp_angle(x) / PI - 1.0, 2.0));
+}
+
+// Adapted from http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+highp float noise(float x)
+{
+    highp float a = 12.9898;
+    highp float b = 78.233;
+    highp float c = 43758.5453;
+    highp float dt = x * a;
+    highp float sn = mod(dt, PI);
+    return fract(sin(sn) * c) * 2.0 - 1.0;
+}
+
+// Interpolate between two random points
+float smooth_noise(float x)
+{
+    float x_fract = fract(x);
+    float x_int = x - x_fract;
+    float n1 = noise(x_int);
+    float n2 = noise(x_int + 1.0);
+    return (n1 * (1.0 - x_fract) + n2 * x_fract);
+}
+
+vec2 displace(vec2 uv)
+{
+    float rad = angle / 180.0 * PI;
+    vec2 normal = vec2(cos(rad), sin(rad));
+    rad -= PI /2.0;
+    vec2 direction = vec2(cos(rad), sin(rad));
+    float x = length(project(uv, direction));
+
+    x = x / wavelength * PI - time * speed * TAU + phase / 180.0 * PI;
+
+
+    float y;
+
+    if ( shape == 1 ) // sine
+        y = sin(x);
+    else if ( shape == 2 ) // square
+        y = clamp_angle(x) < PI ? 1.0 : -1.0;
+    else if ( shape == 3 ) // triangle
+        y = 1.0 - abs(clamp_angle(x) - PI) / PI * 2.0;
+    else if ( shape == 4 ) // sawtooth
+        y = 1.0 - clamp_angle(x) / PI;
+    else if ( shape == 5 ) // circle
+        y = sign(clamp_angle(x) -  PI) * semicircle(2.0 * x);
+    else if ( shape == 6 ) // semi circle
+        y = 2.0 * semicircle(x) - 1.0;
+    else if ( shape == 7 ) // uncircle
+        y = sign(clamp_angle(-x) -  PI) * (semicircle(2.0 * x) - 1.0);
+    else if ( shape == 8 ) // noise
+        y = noise(x);
+    else if ( shape == 9 ) // smooth noise
+        y = smooth_noise(x * 4.0) ;
+
+    return uv + y * normal * amplitude;
+
+}
+
+void main()
+{
+    vec2 uv = displace(gl_FragCoord.xy);
+    gl_FragColor = texture2D(texture_sampler, normalize_uv(uv));
+}
+
+ +
+

+
+
+ + +
+ + + +
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/schema/animated-properties/animated-property.json b/schema/animated-properties/animated-property.json new file mode 100644 index 00000000..8653452d --- /dev/null +++ b/schema/animated-properties/animated-property.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Animated Property", + "description": "An animatable property that holds an array of numbers", + "allOf": [ + { + "properties": { + "ix": { + "title": "Property Index", + "type": "integer" + }, + "a": { + "title": "Animated", + "description": "Whether the property is animated", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "x": { + "title": "Expression", + "type": "string" + }, + "sid": { + "title": "Slot ID", + "description": "One of the ID in the file's slots", + "type": "string" + } + } + }, + { + "if": { + "properties": { + "a": { "const": 1 } + } + }, + "then": { + "properties": { + "k": { + "type": "array", + "title": "Animated Value", + "description": "Array of keyframes", + "items": { + "$ref": "#/$defs/animated-properties/keyframe" + } + } + } + } + } + ], + "required": ["k"] +} diff --git a/schema/animated-properties/color-value.json b/schema/animated-properties/color-value.json new file mode 100644 index 00000000..acf919a6 --- /dev/null +++ b/schema/animated-properties/color-value.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Color Value", + "description": "An animatable property that holds a Color", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/animated-property" + }, + { + "if": { + "properties": { + "a": { "const": 0 } + } + }, + "then": { + "properties": { + "k": { + "title": "Static value", + "$ref": "#/$defs/helpers/color" + } + } + } + } + ] +} diff --git a/schema/animated-properties/gradient-colors.json b/schema/animated-properties/gradient-colors.json new file mode 100644 index 00000000..cb5659e9 --- /dev/null +++ b/schema/animated-properties/gradient-colors.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Gradient Colors", + "description": "Represents colors and offsets in a gradient\n\nColors are represented as a flat list interleaving offsets and color components in weird ways\nThere are two possible layouts:\n\nWithout alpha, the colors are a sequence of offset, r, g, b\n\nWith alpha, same as above but at the end of the list there is a sequence of offset, alpha", + + "properties": { + "k": { + "title": "Colors", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "p": { + "title": "Count", + "description": "Number of colors in `k`", + "type": "integer", + "default": 0 + } + }, + "required": ["p", "k"] +} diff --git a/schema/animated-properties/keyframe-base.json b/schema/animated-properties/keyframe-base.json new file mode 100644 index 00000000..83172beb --- /dev/null +++ b/schema/animated-properties/keyframe-base.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Base Keyframe", + "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.", + "allOf": [ + { + "properties": { + "t": { + "title": "Time", + "type": "number", + "default": 0 + }, + "h": { + "title": "Hold", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + } + }, + { + "if": { + "oneOf": [ + { + "properties": { + "h": { "const": 0 } + } + }, + { + "not": {"required": ["h"]} + } + ] + }, + "then": { + "properties": { + "i": { + "title": "In Tangent", + "description": "Easing tangent going into the next keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + }, + "o": { + "title": "Out Tangent", + "description": "Easing tangent leaving the current keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + } + } + } + } + ], + "required": ["t", "s"] +} + diff --git a/schema/animated-properties/keyframe-bezier-handle.json b/schema/animated-properties/keyframe-bezier-handle.json new file mode 100644 index 00000000..b04fb055 --- /dev/null +++ b/schema/animated-properties/keyframe-bezier-handle.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Keyframe Bezier Handle", + "description": "Bezier handle for keyframe interpolation", + "properties": { + "x": { + "title": "X", + "description": "Time component:\n0 means start time of the keyframe,\n1 means time of the next keyframe.", + "oneOf":[ + { + "type": "array", + "items": { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + }, + "minItems": 1 + }, + { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + } + ] + }, + "y": { + "title": "Y", + "description": "Value interpolation component:\n0 means start value of the keyframe,\n1 means value at the next keyframe.", + "oneOf": [ + { + "type": "array", + "items": { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + }, + "minItems": 1 + }, + { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + } + ] + } + }, + "required": ["x", "y"] +} diff --git a/schema/animated-properties/keyframe.json b/schema/animated-properties/keyframe.json new file mode 100644 index 00000000..c7bf1e7a --- /dev/null +++ b/schema/animated-properties/keyframe.json @@ -0,0 +1,61 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Keyframe", + "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/keyframe-base" + }, + { + "properties": { + "s": { + "title": "Value", + "description": "Value at this keyframe. Note the if the property is a scalar, keyframe values are still represented as arrays", + "type": "array", + "items": { + "type": "number" + } + }, + "e": { + "title": "End value", + "description": "Value at the end of the keyframe, note that this is deprecated and you should use `s` from the next keyframe to get this value", + "deprecated": true, + "type": "array", + "items": { + "type": "number" + } + } + } + }, + { + "if": { + "oneOf": [ + { + "properties": { + "h": { "const": 0 } + } + }, + { + "not": {"required": ["h"]} + } + ] + }, + "then": { + "properties": { + "i": { + "title": "In Tangent", + "description": "Easing tangent going into the next keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + }, + "o": { + "title": "Out Tangent", + "description": "Easing tangent leaving the current keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + } + } + } + } + ], + "required": ["t", "s"] +} diff --git a/schema/animated-properties/multi-dimensional.json b/schema/animated-properties/multi-dimensional.json new file mode 100644 index 00000000..3c3b2985 --- /dev/null +++ b/schema/animated-properties/multi-dimensional.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Multi Dimensional", + "description": "An animatable property that holds an array of numbers", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/animated-property" + }, + { + "if": { + "properties": { + "a": { "const": 0 } + } + }, + "then": { + "properties": { + "k": { + "title": "Static value", + "type": "array", + "items": { + "type": "number" + } + } + } + }, + "properties": { + "l": { + "title": "Length", + "description": "Number of components in the value arrays.\nIf present values will be truncated or expanded to match this length when accessed from expressions.", + "type": "integer" + } + } + } + ] +} diff --git a/schema/animated-properties/position-keyframe.json b/schema/animated-properties/position-keyframe.json new file mode 100644 index 00000000..34ae9860 --- /dev/null +++ b/schema/animated-properties/position-keyframe.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Position Keyframe", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/keyframe" + }, + { + "properties": { + "ti": { + "title": "Value In Tangent", + "description": "Tangent for values (eg: moving position around a curved path)", + "type": "array", + "items": { + "type": "number" + } + }, + "to": { + "title": "Value Out Tangent", + "description": "Tangent for values (eg: moving position around a curved path)", + "type": "array", + "items": { + "type": "number" + } + } + } + } + ] +} diff --git a/schema/animated-properties/position.json b/schema/animated-properties/position.json new file mode 100644 index 00000000..61887058 --- /dev/null +++ b/schema/animated-properties/position.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Position Property", + "description": "An animatable property to represent a position in space", + "allOf": [ + { + "properties": { + "ix": { + "title": "Property Index", + "type": "integer" + }, + "a": { + "title": "Animated", + "description": "Whether the property is animated", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "x": { + "title": "Expression", + "type": "string" + }, + "l": { + "title": "Length", + "description": "Number of components in the value arrays.\nIf present values will be truncated or expanded to match this length when accessed from expressions.", + "type": "integer" + } + } + }, + { + "if": { + "properties": { + "a": { "const": 1 } + } + }, + "then": { + "properties": { + "k": { + "type": "array", + "title": "Animated Value", + "description": "Array of keyframes", + "items": { + "$ref": "#/$defs/animated-properties/position-keyframe" + } + } + } + }, + "else": { + "properties": { + "k": { + "title": "Static Value", + "type": "array", + "items": { + "type": "number" + } + } + } + } + } + ], + "required": ["k"] +} + diff --git a/schema/animated-properties/shape-keyframe.json b/schema/animated-properties/shape-keyframe.json new file mode 100644 index 00000000..211921ba --- /dev/null +++ b/schema/animated-properties/shape-keyframe.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Shape Keyframe", + "description": "Keyframe holding Bezier objects", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/keyframe-base" + }, + { + "type": "object", + "properties": { + "s": { + "title": "Start", + "type": "array", + "items": { + "$ref": "#/$defs/helpers/bezier" + } + } + } + } + ] +} diff --git a/schema/animated-properties/shape-property.json b/schema/animated-properties/shape-property.json new file mode 100644 index 00000000..4e80726b --- /dev/null +++ b/schema/animated-properties/shape-property.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Shape Property", + "description": "An animatable property that holds a Bezier", + "allOf": [ + { + "properties": { + "ix": { + "title": "Property Index", + "type": "integer" + }, + "a": { + "title": "Animated", + "description": "Whether the property is animated", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "x": { + "title": "Expression", + "type": "string" + } + } + }, + { + "if": { + "properties": { + "a": { "const": 1 } + } + }, + "then": { + "properties": { + "k": { + "type": "array", + "title": "Animated Value", + "description": "Array of keyframes", + "items": { + "$ref": "#/$defs/animated-properties/shape-keyframe" + } + } + } + }, + "else": { + "properties": { + "k": { + "$ref": "#/$defs/helpers/bezier", + "title": "Static Value" + } + } + } + } + ], + "required": ["k"] +} diff --git a/schema/animated-properties/split-vector.json b/schema/animated-properties/split-vector.json new file mode 100644 index 00000000..7b376bff --- /dev/null +++ b/schema/animated-properties/split-vector.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Split Vector", + "description": "An animatable property that is split into individually anaimated components", + "properties": { + "s": { + "title": "Split", + "type": "boolean", + "const": true + }, + "x": { + "title": "X", + "$ref": "#/$defs/animated-properties/value" + }, + "y": { + "title": "Y", + "$ref": "#/$defs/animated-properties/value" + }, + "z": { + "title": "Z", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["s", "x", "y"] +} + + diff --git a/schema/animated-properties/value.json b/schema/animated-properties/value.json new file mode 100644 index 00000000..56281e99 --- /dev/null +++ b/schema/animated-properties/value.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Value", + "description": "An animatable property that holds a float", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/animated-property" + }, + { + "if": { + "properties": { + "a": { "const": 0 } + } + }, + "then": { + "properties": { + "k": { + "title": "Static value", + "type": "number" + } + } + } + } + ] +} diff --git a/schema/animation/animation.json b/schema/animation/animation.json new file mode 100644 index 00000000..d561c154 --- /dev/null +++ b/schema/animation/animation.json @@ -0,0 +1,158 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Animation", + "description": "Top level object, describing the animation", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "v": { + "title": "Version", + "type": "string", + "default": "5.5.2" + }, + "fr": { + "title": "Framerate", + "description": "Framerate in frames per second", + "type": "number", + "default": 60 + }, + "ip": { + "title": "In Point", + "description": "\"In Point\", which frame the animation starts at (usually 0)", + "type": "number", + "default": 0 + }, + "op": { + "title": "Out Point", + "description": "\"Out Point\", which frame the animation stops/loops at, which makes this the duration in frames when `ip` is 0", + "type": "number", + "default": 60 + }, + "w": { + "title": "Width", + "description": "Width of the animation", + "type": "integer", + "default": 512 + }, + "h": { + "title": "Height", + "description": "Height of the animation", + "type": "integer", + "default": 512 + }, + "ddd": { + "title": "Threedimensional", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0, + "description": "Whether the animation has 3D layers" + }, + "assets": { + "title": "Assets", + "type": "array", + "description": "List of assets that can be referenced by layers", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/assets/image" + }, + { + "$ref": "#/$defs/assets/precomposition" + }, + { + "$ref": "#/$defs/assets/sound" + }, + { + "$ref": "#/$defs/assets/data-source" + } + ] + } + }, + "comps": { + "title": "Extra Compositions", + "type": "array", + "description": "List of Extra compositions not referenced by anything", + "items": { + "$ref": "#/$defs/assets/precomposition" + } + }, + "fonts": { + "title": "Fonts", + "$ref": "#/$defs/text/font-list" + }, + "chars": { + "title": "Characters", + "description": "Data defining text characters as lottie shapes. If present a player might only render characters defined here and nothing else.", + "type": "array", + "items": { + "$ref": "#/$defs/text/character-data" + } + }, + "meta": { + "title": "Metadata", + "description": "Document metadata", + "$ref": "#/$defs/animation/metadata" + }, + "metadata": { + "title": "User Metadata", + "$ref": "#/$defs/animation/user-metadata" + }, + "markers": { + "title": "Markers", + "description": "Markers defining named sections of the composition.", + "type": "array", + "items": { + "$ref": "#/$defs/helpers/marker" + } + }, + "mb": { + "title": "Motion Blur", + "$ref": "#/$defs/animation/motion-blur" + }, + "slots": { + "title": "Slots", + "description": "Available property overrides", + "type": "object", + "patternProperties": { + ".*": { + "p": { + "anyOf": [ + { + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + { + "$ref": "#/$defs/animated-properties/color-value" + }, + { + "$ref": "#/$defs/animated-properties/position" + }, + { + "$ref": "#/$defs/animated-properties/shape-property" + }, + { + "$ref": "#/$defs/animated-properties/value" + }, + { + "$ref": "#/$defs/assets/image" + }, + { + "$ref": "#/$defs/text/animated-text-document" + } + ] + }, + "required": ["p"] + } + } + } + }, + "required": ["w", "h", "fr", "layers", "op", "ip"] + }, + { + "$ref": "#/$defs/animation/composition" + } + ] +} diff --git a/schema/animation/composition.json b/schema/animation/composition.json new file mode 100644 index 00000000..544f8cb7 --- /dev/null +++ b/schema/animation/composition.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Composition", + "description": "Base class for layer holders", + "properties": { + "layers": { + "title": "Layers", + "type": "array", + "items": { + "oneOf": [ + {"$ref": "#/$defs/layers/precomposition-layer"}, + {"$ref": "#/$defs/layers/solid-color-layer"}, + {"$ref": "#/$defs/layers/image-layer"}, + {"$ref": "#/$defs/layers/null-layer"}, + {"$ref": "#/$defs/layers/shape-layer"}, + {"$ref": "#/$defs/layers/text-layer"}, + {"$ref": "#/$defs/layers/audio-layer"}, + {"$ref": "#/$defs/layers/camera-layer"}, + {"$ref": "#/$defs/layers/data-layer"} + ] + } + } + }, + "required": ["layers"] +} diff --git a/schema/animation/metadata.json b/schema/animation/metadata.json new file mode 100644 index 00000000..d2498193 --- /dev/null +++ b/schema/animation/metadata.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Metadata", + "description": "Document metadata", + "properties": { + "a": { + "title": "Author", + "type": "string" + }, + "d": { + "title": "Description", + "type": "string" + }, + "tc": { + "title": "Theme Color", + "type": "string" + }, + "g": { + "title": "Generator", + "description": "Software used to generate the file", + "type": "string" + } + }, + "anyOf": [ + { + "properties": { + "k": { + "title": "Keywords", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + { + "properties": { + "k": { + "title": "Keywords", + "type": "string" + } + } + } + ] +} diff --git a/schema/animation/motion-blur.json b/schema/animation/motion-blur.json new file mode 100644 index 00000000..48b6bf50 --- /dev/null +++ b/schema/animation/motion-blur.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Motion Blur", + "description": "Motion blur settings", + "properties": { + "sa": { + "title": "Shutter Angle", + "description": "Angle in degrees", + "type": "number" + }, + "sp": { + "title": "Shutter Phase", + "description": "Angle in degrees", + "type": "number" + }, + "spf": { + "title": "Samples per Frame", + "type": "number" + }, + "asl": { + "title": "Adaptive Sample Limit", + "type": "number" + } + } +} + diff --git a/schema/animation/user-metadata.json b/schema/animation/user-metadata.json new file mode 100644 index 00000000..50ef11a9 --- /dev/null +++ b/schema/animation/user-metadata.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "User Metadata", + "description": "User-defined metadata", + "properties": { + "filename": { + "title": "Filename", + "type": "string" + }, + "customProps": { + "title": "Custom Properties", + "type": "object" + } + } +} + diff --git a/schema/assets/asset.json b/schema/assets/asset.json new file mode 100644 index 00000000..eb87d45d --- /dev/null +++ b/schema/assets/asset.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Asset", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "Unique identifier used by layers when referencing this asset", + "type": "string", + "default": "" + }, + "nm": { + "title": "Name", + "description": "Human readable name", + "type": "string" + } + }, + "required": ["id"] + } + ] +} diff --git a/schema/assets/data-source.json b/schema/assets/data-source.json new file mode 100644 index 00000000..3ff66dc3 --- /dev/null +++ b/schema/assets/data-source.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Data source", + "description": "External data source, usually a JSON file", + "allOf": [ + { + "$ref": "#/$defs/assets/file-asset" + }, + { + "type": "object", + "properties": { + "t": { + "title": "Type", + "type": "integer", + "const": 3 + } + }, + "required": ["t"] + } + ] +} + diff --git a/schema/assets/file-asset.json b/schema/assets/file-asset.json new file mode 100644 index 00000000..545aecf2 --- /dev/null +++ b/schema/assets/file-asset.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "File Asset", + "description": "Asset referencing a file", + "allOf": [ + { + "$ref": "#/$defs/assets/asset" + }, + { + "type": "object", + "properties": { + "u": { + "title": "Path", + "description": "Path to the directory containing a file", + "type": "string", + "default": "" + }, + "p": { + "title": "File name", + "description": "Filename or data url", + "type": "string", + "default": "" + }, + "e": { + "title": "Embedded", + "description": "Whether the file is embedded", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + }, + "required": ["p"] + } + ] +} + + diff --git a/schema/assets/image.json b/schema/assets/image.json new file mode 100644 index 00000000..4302b642 --- /dev/null +++ b/schema/assets/image.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Image", + "description": "External image", + "allOf": [ + { + "$ref": "#/$defs/assets/file-asset" + }, + { + "type": "object", + "properties": { + "w": { + "title": "Width", + "description": "Width of the image", + "type": "number", + "default": 0 + }, + "h": { + "title": "Height", + "description": "Height of the image", + "type": "number", + "default": 0 + }, + "t": { + "title": "Type", + "description": "Marks as part of an image sequence if present", + "type": "string", + "const": "seq" + }, + "sid": { + "title": "Slot ID", + "description": "One of the ID in the file's slots", + "type": "string" + } + }, + "required": ["p"] + } + ] +} diff --git a/schema/assets/precomposition.json b/schema/assets/precomposition.json new file mode 100644 index 00000000..b6e4cfa3 --- /dev/null +++ b/schema/assets/precomposition.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Precomposition", + "description": "Asset containing an animation that can be referenced by layers.", + "allOf": [ + { + "$ref": "#/$defs/assets/asset" + }, + { + "$ref": "#/$defs/animation/composition" + }, + { + "type": "object", + "properties": { + "fr": { + "title": "Framerate", + "description": "Framerate in frames per second", + "type": "number" + }, + "xt": { + "title": "Extra", + "description": "Extra composition", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + } + } + ] +} diff --git a/schema/assets/sound.json b/schema/assets/sound.json new file mode 100644 index 00000000..683e90c8 --- /dev/null +++ b/schema/assets/sound.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Sound", + "description": "External sound", + "allOf": [ + { + "$ref": "#/$defs/assets/file-asset" + } + ] +} diff --git a/schema/constants/blend-mode.json b/schema/constants/blend-mode.json new file mode 100644 index 00000000..1407446e --- /dev/null +++ b/schema/constants/blend-mode.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Blend Mode", + "description": "Layer and shape blend mode", + "caniuse": "blend-mode", + "oneOf": [ + { + "title": "Normal", + "const": 0 + }, + { + "title": "Multiply", + "const": 1 + }, + { + "title": "Screen", + "const": 2 + }, + { + "title": "Overlay", + "const": 3 + }, + { + "title": "Darken", + "const": 4 + }, + { + "title": "Lighten", + "const": 5 + }, + { + "title": "Color Dodge", + "const": 6 + }, + { + "title": "Color Burn", + "const": 7 + }, + { + "title": "Hard Light", + "const": 8 + }, + { + "title": "Soft Light", + "const": 9 + }, + { + "title": "Difference", + "const": 10 + }, + { + "title": "Exclusion", + "const": 11 + }, + { + "title": "Hue", + "const": 12 + }, + { + "title": "Saturation", + "const": 13 + }, + { + "title": "Color", + "const": 14 + }, + { + "title": "Luminosity", + "const": 15 + }, + { + "title": "Add", + "const": 16 + }, + { + "title": "Hard Mix", + "const": 17 + } + ] +} diff --git a/schema/constants/composite.json b/schema/constants/composite.json new file mode 100644 index 00000000..55079293 --- /dev/null +++ b/schema/constants/composite.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Composite", + "description": "How to stack copies in a repeater", + "oneOf": [ + { + "title": "Below", + "description": "Subsequent copies are added underneath the previous ones.", + "const": 1 + }, + { + "title": "Above", + "description": "Subsequent copies are added on top of the previous ones.", + "const": 2 + } + ] +} diff --git a/schema/constants/fill-rule.json b/schema/constants/fill-rule.json new file mode 100644 index 00000000..166da4b0 --- /dev/null +++ b/schema/constants/fill-rule.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Fill Rule", + "description": "Rule used to handle multiple shapes rendered with the same fill object", + "oneOf": [ + { + "title": "Non Zero", + "description": "Everything is colored (You can think of this as an OR)", + "const": 1 + }, + { + "title": "Even Odd", + "description": "Colored based on intersections and path direction, can be used to create \"holes\"", + "const": 2 + } + ] +} diff --git a/schema/constants/font-path-origin.json b/schema/constants/font-path-origin.json new file mode 100644 index 00000000..48fd15e3 --- /dev/null +++ b/schema/constants/font-path-origin.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Font Path Origin", + "description": "", + "oneOf": [ + { + "title": "Local", + "const": 0 + }, + { + "title": "Css Url", + "const": 1 + }, + { + "title": "Script Url", + "const": 2 + }, + { + "title": "Font Url", + "const": 3 + } + ] +} diff --git a/schema/constants/gradient-type.json b/schema/constants/gradient-type.json new file mode 100644 index 00000000..af3a54f9 --- /dev/null +++ b/schema/constants/gradient-type.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Gradient Type", + "description": "Type of a gradient", + "oneOf": [ + { + "title": "Linear", + "type": "integer", + "const": 1 + }, + { + "title": "Radial", + "type": "integer", + "const": 2 + } + ] +} diff --git a/schema/constants/line-cap.json b/schema/constants/line-cap.json new file mode 100644 index 00000000..cefd7042 --- /dev/null +++ b/schema/constants/line-cap.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Line Cap", + "description": "Style at the end of a stoked line", + "oneOf": [ + { + "title": "Butt", + "const": 1 + }, + { + "title": "Round", + "const": 2 + }, + { + "title": "Square", + "const": 3 + } + ] +} diff --git a/schema/constants/line-join.json b/schema/constants/line-join.json new file mode 100644 index 00000000..327e7d2f --- /dev/null +++ b/schema/constants/line-join.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Line Join", + "description": "Style at a sharp corner of a stoked line", + "oneOf": [ + { + "title": "Miter", + "const": 1 + }, + { + "title": "Round", + "const": 2 + }, + { + "title": "Bevel", + "const": 3 + } + ] +} diff --git a/schema/constants/mask-mode.json b/schema/constants/mask-mode.json new file mode 100644 index 00000000..2a8c8e2a --- /dev/null +++ b/schema/constants/mask-mode.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "title": "Mask Mode", + "description": "How masks interact with each other. See https://helpx.adobe.com/after-effects/using/alpha-channels-masks-mattes.html", + "oneOf": [ + { + "title": "None", + "const": "n" + }, + { + "title": "Add", + "const": "a" + }, + { + "title": "Subtract", + "const": "s" + }, + { + "title": "Intersect", + "const": "i" + }, + { + "title": "Lighten", + "const": "l" + }, + { + "title": "Darken", + "const": "d" + }, + { + "title": "Difference", + "const": "f" + } + ] +} diff --git a/schema/constants/matte-mode.json b/schema/constants/matte-mode.json new file mode 100644 index 00000000..d56f6ba4 --- /dev/null +++ b/schema/constants/matte-mode.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Matte Mode", + "description": "How a layer should mask another layer", + "oneOf": [ + { + "title": "Normal", + "const": 0 + }, + { + "title": "Alpha", + "const": 1 + }, + { + "title": "Inverted Alpha", + "const": 2 + }, + { + "title": "Luma", + "const": 3 + }, + { + "title": "Inverted Luma", + "const": 4 + } + ] +} diff --git a/schema/constants/merge-mode.json b/schema/constants/merge-mode.json new file mode 100644 index 00000000..efa5ffd0 --- /dev/null +++ b/schema/constants/merge-mode.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Merge Mode", + "description": "Boolean operation on shapes", + "oneOf": [ + { + "title": "Normal", + "const": 1 + }, + { + "title": "Add", + "const": 2 + }, + { + "title": "Subtract", + "const": 3 + }, + { + "title": "Intersect", + "const": 4 + }, + { + "title": "Exclude Intersections", + "const": 5 + } + ] +} + diff --git a/schema/constants/shape-direction.json b/schema/constants/shape-direction.json new file mode 100644 index 00000000..ec943aff --- /dev/null +++ b/schema/constants/shape-direction.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Shape Direction", + "description": "Drawing direction of the shape curve, useful for trim path", + "oneOf": [ + { + "title": "Normal", + "description": "Usually clockwise", + "const": 1 + }, + { + "title": "Reversed", + "description": "Usually counter clockwise", + "const": 3 + } + ] +} diff --git a/schema/constants/star-type.json b/schema/constants/star-type.json new file mode 100644 index 00000000..3d54fb94 --- /dev/null +++ b/schema/constants/star-type.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Star Type", + "description": "Star or Polygon", + "oneOf": [ + { + "title": "Star", + "const": 1 + }, + { + "title": "Polygon", + "const": 2 + } + ] +} diff --git a/schema/constants/stroke-dash-type.json b/schema/constants/stroke-dash-type.json new file mode 100644 index 00000000..9a3a37d9 --- /dev/null +++ b/schema/constants/stroke-dash-type.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "string", + "title": "Stroke Dash Type", + "description": "Type of a dash item in a stroked line", + "oneOf": [ + { + "title": "Dash", + "const": "d" + }, + { + "title": "Gap", + "const": "g" + }, + { + "title": "Offset", + "const": "o" + } + ] +} diff --git a/schema/constants/text-based.json b/schema/constants/text-based.json new file mode 100644 index 00000000..84366b5f --- /dev/null +++ b/schema/constants/text-based.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Text Based", + "description": "", + "oneOf": [ + { + "title": "Characters", + "const": 1 + }, + { + "title": "Character Excluding Spaces", + "const": 2 + }, + { + "title": "Words", + "const": 3 + }, + { + "title": "Lines", + "const": 4 + } + ] +} diff --git a/schema/constants/text-caps.json b/schema/constants/text-caps.json new file mode 100644 index 00000000..d5288c33 --- /dev/null +++ b/schema/constants/text-caps.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Text Caps", + "oneOf": [ + { + "title": "Regular", + "const": 0 + }, + { + "title": "All Caps", + "const": 1 + }, + { + "title": "Small Caps", + "const": 2 + } + ], + "default": 0 +} diff --git a/schema/constants/text-grouping.json b/schema/constants/text-grouping.json new file mode 100644 index 00000000..01f8a865 --- /dev/null +++ b/schema/constants/text-grouping.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Text Grouping", + "description": "", + "oneOf": [ + { + "title": "Characters", + "const": 1 + }, + { + "title": "Word", + "const": 2 + }, + { + "title": "Line", + "const": 3 + }, + { + "title": "All", + "const": 4 + } + ] +} diff --git a/schema/constants/text-justify.json b/schema/constants/text-justify.json new file mode 100644 index 00000000..47e1921e --- /dev/null +++ b/schema/constants/text-justify.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Text Justify", + "description": "Text alignment / justification", + "oneOf": [ + { + "title": "Left", + "const": 0 + }, + { + "title": "Right", + "const": 1 + }, + { + "title": "Center", + "const": 2 + }, + { + "title": "Justify with Last Line Left", + "const": 3 + }, + { + "title": "Justify with Last Line Right", + "const": 4 + }, + { + "title": "Justify with Last Line Center", + "const": 5 + }, + { + "title": "Justify with Last Line Full", + "const": 6 + } + ] +} diff --git a/schema/constants/text-range-units.json b/schema/constants/text-range-units.json new file mode 100644 index 00000000..5bef5301 --- /dev/null +++ b/schema/constants/text-range-units.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Text Range Units", + "description": "Unit type for a text selector", + "oneOf": [ + { + "title": "Percent", + "const": 1 + }, + { + "title": "Index", + "const": 2 + } + ] +} + diff --git a/schema/constants/text-shape.json b/schema/constants/text-shape.json new file mode 100644 index 00000000..585f8f68 --- /dev/null +++ b/schema/constants/text-shape.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Text Shape", + "description": "Defines the function used to determine the interpolating factor on a text range selector.", + "oneOf": [ + { + "title": "Square", + "const": 1 + }, + { + "title": "Ramp Up", + "const": 2 + }, + { + "title": "Ramp Down", + "const": 3 + }, + { + "title": "Triangle", + "const": 4 + }, + { + "title": "Round", + "const": 5 + }, + { + "title": "Smooth", + "const": 6 + } + ] +} diff --git a/schema/constants/trim-multiple-shapes.json b/schema/constants/trim-multiple-shapes.json new file mode 100644 index 00000000..304e615a --- /dev/null +++ b/schema/constants/trim-multiple-shapes.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Trim Multiple Shapes", + "description": "How to handle multiple shapes in trim path", + "oneOf": [ + { + "title": "Simultaneously", + "const": 1 + }, + { + "title": "Individually", + "const": 2 + } + ] +} diff --git a/schema/docs_mapping.json b/schema/docs_mapping.json new file mode 100644 index 00000000..ef33d756 --- /dev/null +++ b/schema/docs_mapping.json @@ -0,0 +1,139 @@ +{ + "animated-properties": { + "_defaults": { + "page": "concepts", + "anchor": "animated-property" + }, + "value": { + "name_prefix": "Animated ", + "name": "number" + }, + "multi-dimensional": { + "name_prefix": "Animated ", + "name": "Vector" + }, + "color-value": { + "name_prefix": "", + "name": "Animated", + "extra": { + "page": "concepts", + "anchor": "colors", + "name": "Color" + } + }, + "shape-property": { + "name_prefix": "", + "name": "Animated", + "extra": { + "page": "concepts", + "anchor": "bezier", + "name": "Bezier" + } + }, + "position": { + "name_prefix": "Animated ", + "anchor": "animated-position", + "name": "Position" + }, + "gradient-colors": { + "anchor": "gradients" + } + }, + "shapes": { + "gradient": { + "anchor": "gradients" + }, + "gradient-fill": { + "anchor": "gradients" + }, + "gradient-stroke": { + "anchor": "gradients" + }, + "shape-element": { + "anchor": "shape-elements" + }, + "base-stroke": { + "anchor": "stroke" + }, + "trim": { + "anchor": "trim-path" + }, + "shape-list": { + "page": "concepts", + "anchor": "lists-of-layers-and-shapes" + }, + "transform": { + "anchor": "transform-shape" + }, + "modifier": { + "anchor": "modifiers" + }, + "stroke-dash": { + "anchor": "stroke-dashes" + } + }, + "helpers": { + "_defaults": { + "page": "concepts" + }, + "mask": { + "page": "layers", + "anchor": "masks" + }, + "color": { + "anchor": "colors" + }, + "int-boolean": { + "anchor": "booleans", + "name": "0-1 Integer" + }, + "visual-object": { + "page": null + }, + "marker": { + "page": "animation" + } + }, + "effect-values": { + "_defaults": { + "page": "effects" + }, + "effect-value": { + "anchor": "effect-values" + } + }, + "styles": { + "_defaults": { + "page": "effects" + } + }, + "text": { + "font": { + "anchor": "font-list" + } + }, + "effects": { + "effect":{ + "anchor": "effects" + } + }, + "assets": { + "asset":{ + "anchor": "assets" + }, + "file-asset": { + "anchor": "data-source" + } + }, + "animation": { + "composition":{ + "page": "concepts", + "anchor": "lists-of-layers-and-shapes" + } + }, + "layers": { + "visual-layer":{ + "anchor": "layer" + } + } +} diff --git a/schema/effect-values/angle.json b/schema/effect-values/angle.json new file mode 100644 index 00000000..b0893dc4 --- /dev/null +++ b/schema/effect-values/angle.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Angle", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 1 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/checkbox.json b/schema/effect-values/checkbox.json new file mode 100644 index 00000000..04242d16 --- /dev/null +++ b/schema/effect-values/checkbox.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Checkbox", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 4 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/color.json b/schema/effect-values/color.json new file mode 100644 index 00000000..3df28a06 --- /dev/null +++ b/schema/effect-values/color.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Color", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 2 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/color-value" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/drop-down.json b/schema/effect-values/drop-down.json new file mode 100644 index 00000000..861e681e --- /dev/null +++ b/schema/effect-values/drop-down.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Drop Down", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 7 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/effect-value.json b/schema/effect-values/effect-value.json new file mode 100644 index 00000000..25fe0ac2 --- /dev/null +++ b/schema/effect-values/effect-value.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value", + "description": "Value for an effect", + "caniuse": "effects", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ix": { + "title": "Effect Index", + "type": "integer" + }, + "mn": { + "title": "Match Name", + "type": "string" + }, + "nm": { + "title": "Name", + "type": "string" + }, + "ty": { + "title": "Type", + "type": "integer" + } + }, + "required": [] + } + ] +} diff --git a/schema/effect-values/ignored.json b/schema/effect-values/ignored.json new file mode 100644 index 00000000..823c0575 --- /dev/null +++ b/schema/effect-values/ignored.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Ignored Value", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 6 + }, + "v": { + "title": "Value", + "type": "number", + "default": 0 + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/layer.json b/schema/effect-values/layer.json new file mode 100644 index 00000000..d93bff7c --- /dev/null +++ b/schema/effect-values/layer.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Layer", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 10 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/no-value.json b/schema/effect-values/no-value.json new file mode 100644 index 00000000..e869ed93 --- /dev/null +++ b/schema/effect-values/no-value.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect No Value", + "description": "" +} diff --git a/schema/effect-values/point.json b/schema/effect-values/point.json new file mode 100644 index 00000000..a22daebf --- /dev/null +++ b/schema/effect-values/point.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Point", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 3 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effect-values/slider.json b/schema/effect-values/slider.json new file mode 100644 index 00000000..a729c2cb --- /dev/null +++ b/schema/effect-values/slider.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect Value Slider", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 0 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effects/custom-effect.json b/schema/effects/custom-effect.json new file mode 100644 index 00000000..83cb8406 --- /dev/null +++ b/schema/effects/custom-effect.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Custom Effect", + "description": "Some lottie files use `ty` = 5 for many different effects", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 5 + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/displacement-map-effect.json b/schema/effects/displacement-map-effect.json new file mode 100644 index 00000000..1c5e690d --- /dev/null +++ b/schema/effects/displacement-map-effect.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Displacement Map Effect", + "description": "", + "caniuse": "effect-displacement-map", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 27 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Displacement Map Layer", + "$ref": "#/$defs/effect-values/layer" + }, + { + "title": "Use For Horizontal Displacement", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Max Horizontal Displacement", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Use For Vertical Displacement", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Max Vertical Displacement", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Displacement Map Behavior", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Edge Behavior", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Expand Output", + "$ref": "#/$defs/effect-values/drop-down" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] +} diff --git a/schema/effects/drop-shadow-effect.json b/schema/effects/drop-shadow-effect.json new file mode 100644 index 00000000..3cd72711 --- /dev/null +++ b/schema/effects/drop-shadow-effect.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Drop Shadow Effect", + "description": "Adds a shadow to the layer", + "caniuse": "effect-drop-shadow", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 25 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "color", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "opacity", + "description": "Opacity between 0 and 255", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "angle", + "$ref": "#/$defs/effect-values/angle" + }, + { + "title": "distance", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "blur", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/effect.json b/schema/effects/effect.json new file mode 100644 index 00000000..6bdf28b8 --- /dev/null +++ b/schema/effects/effect.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Effect", + "description": "Layer effect", + "caniuse": "effects", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ef": { + "title": "Effect Values", + "type": "array", + "items": { + "oneOf": [ + {"$ref": "#/$defs/effect-values/no-value"}, + {"$ref": "#/$defs/effect-values/angle"}, + {"$ref": "#/$defs/effect-values/checkbox"}, + {"$ref": "#/$defs/effect-values/color"}, + {"$ref": "#/$defs/effect-values/drop-down"}, + {"$ref": "#/$defs/effect-values/ignored"}, + {"$ref": "#/$defs/effect-values/layer"}, + {"$ref": "#/$defs/effect-values/point"}, + {"$ref": "#/$defs/effect-values/slider"} + ] + } + }, + "np": { + "title": "Property Count", + "description": "Number of values in `ef`", + "type": "integer" + }, + "ix": { + "title": "Effect Index", + "type": "integer" + }, + "ty": { + "title": "Type", + "description": "Effect type", + "type": "integer" + }, + "en": { + "title": "Enabled", + "$ref": "#/$defs/helpers/int-boolean", + "default": 1 + } + }, + "required": ["ty", "ef"] + } + ] +} diff --git a/schema/effects/fill-effect.json b/schema/effects/fill-effect.json new file mode 100644 index 00000000..c3699620 --- /dev/null +++ b/schema/effects/fill-effect.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Fill Effect", + "description": "Replaces the whole layer with the given color", + "caniuse": "effect-fill", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 21 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "00", + "$ref": "#/$defs/effect-values/point" + }, + { + "title": "01", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "color", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "03", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "04", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "05", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "opacity", + "description": "Opacity in [0, 1]", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/gaussian-blur-effect.json b/schema/effects/gaussian-blur-effect.json new file mode 100644 index 00000000..b5725daf --- /dev/null +++ b/schema/effects/gaussian-blur-effect.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Gaussian Blur Effect", + "description": "Gaussian blur", + "caniuse": "effect-gaussian-blur", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 29 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "sigma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "direction", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "wrap", + "$ref": "#/$defs/effect-values/checkbox" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/matte3-effect.json b/schema/effects/matte3-effect.json new file mode 100644 index 00000000..af8d3164 --- /dev/null +++ b/schema/effects/matte3-effect.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Set Matte Effect", + "description": "Uses a layer as a mask", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 28 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Layer", + "description": "Use this layer as a mask", + "$ref": "#/$defs/effect-values/layer" + }, + { + "title": "Channel", + "description": "Channel to use as a mask:\n1 - Red\n2 - Green\n3 - Blue\n4 - Alpha\n5 - Luminance\n6 - Hue\n7 - Lightness\n8 - Saturation\n9 - Full\n10 - Off", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Invert", + "description": "Use 0 as opaque value when true", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Stretch To Fit", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Show Mask", + "description": "If false, the mask layer won't be shown", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Premultiply Mask", + "$ref": "#/$defs/effect-values/drop-down" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/mesh-warp-effect.json b/schema/effects/mesh-warp-effect.json new file mode 100644 index 00000000..f559fdc0 --- /dev/null +++ b/schema/effects/mesh-warp-effect.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Mesh Warp Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 31 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Rows", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Columns", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Quality", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "03", + "$ref": "#/$defs/effect-values/no-value" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] +} \ No newline at end of file diff --git a/schema/effects/pro-levels-effect.json b/schema/effects/pro-levels-effect.json new file mode 100644 index 00000000..b9411b5f --- /dev/null +++ b/schema/effects/pro-levels-effect.json @@ -0,0 +1,171 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Pro Levels Effect", + "description": "", + "caniuse": "effect-color-levels-individual-controls", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 24 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "00", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "01", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "02", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "comp_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_outwhite", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "08", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "09", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_outwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "15", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "16", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_outwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "22", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "23", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_outwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "29", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_outwhite", + "$ref": "#/$defs/effect-values/no-value" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/puppet-effect.json b/schema/effects/puppet-effect.json new file mode 100644 index 00000000..a74d5d91 --- /dev/null +++ b/schema/effects/puppet-effect.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Puppet Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 34 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Puppet Engine", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Mesh Rotation Refinement", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "On Transparent", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "03", + "$ref": "#/$defs/effect-values/no-value" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] +} diff --git a/schema/effects/radial-wipe-effect.json b/schema/effects/radial-wipe-effect.json new file mode 100644 index 00000000..7f37c245 --- /dev/null +++ b/schema/effects/radial-wipe-effect.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Radial Wipe", + "caniuse": "effect-radial-wipe", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 26 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Completion", + "description": "Between 0 and 100", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Start Angle", + "$ref": "#/$defs/effect-values/angle" + }, + { + "title": "Wipe Center", + "$ref": "#/$defs/effect-values/point" + }, + { + "title": "Wipe", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Feather", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} + diff --git a/schema/effects/spherize-effect.json b/schema/effects/spherize-effect.json new file mode 100644 index 00000000..dd985665 --- /dev/null +++ b/schema/effects/spherize-effect.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Spherize Effect", + "description": "", + "caniuse": "effect-cc-sphere", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 33 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "radius", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "center", + "$ref": "#/$defs/effect-values/point" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} + diff --git a/schema/effects/stroke-effect.json b/schema/effects/stroke-effect.json new file mode 100644 index 00000000..84800783 --- /dev/null +++ b/schema/effects/stroke-effect.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Stroke Effect", + "description": "", + "caniuse": "effect-stroke", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 22 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "00", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "01", + "$ref": "#/$defs/effect-values/checkbox" + }, + { + "title": "02", + "$ref": "#/$defs/effect-values/checkbox" + }, + { + "title": "color", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "04", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "05", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "06", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "07", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "08", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "09", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "type", + "$ref": "#/$defs/effect-values/drop-down" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/tint-effect.json b/schema/effects/tint-effect.json new file mode 100644 index 00000000..cb922d47 --- /dev/null +++ b/schema/effects/tint-effect.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Tint Effect", + "description": "Colorizes the layer", + "caniuse": "effect-tint", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 20 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Black Color", + "description": "Tint of the darker parts of the layer", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "White Color", + "description": "Tint of the lighter parts of the layer", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "Intensity", + "description": "Intensity of the effect, 0 means the layer is unchanged. 100 means full effect", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/tritone-effect.json b/schema/effects/tritone-effect.json new file mode 100644 index 00000000..b9dc04d8 --- /dev/null +++ b/schema/effects/tritone-effect.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Tritone Effect", + "description": "Maps layers colors based on bright/mid/dark colors", + "caniuse": "effect-tritone", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 23 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "bright", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "mid", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "dark", + "$ref": "#/$defs/effect-values/color" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/effects/twirl-effect.json b/schema/effects/twirl-effect.json new file mode 100644 index 00000000..6123ebf0 --- /dev/null +++ b/schema/effects/twirl-effect.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Twirl Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 30 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Angle", + "$ref": "#/$defs/effect-values/angle" + }, + { + "title": "Radius", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Center", + "$ref": "#/$defs/effect-values/point" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] +} + diff --git a/schema/effects/wavy-effect.json b/schema/effects/wavy-effect.json new file mode 100644 index 00000000..0885e9c9 --- /dev/null +++ b/schema/effects/wavy-effect.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Wavy Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 32 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Radius", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Center", + "$ref": "#/$defs/effect-values/point" + }, + { + "title": "Conversion type", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Speed", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Width", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Height", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Phase", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] +} diff --git a/schema/expressions.json b/schema/expressions.json new file mode 100644 index 00000000..44eaebbb --- /dev/null +++ b/schema/expressions.json @@ -0,0 +1,630 @@ +{ + "variables": { + "$bm_rt": { + "type": "Depends on the property", + "description": "Output value for the expression", + "notes": "Must be declared and be assigned a value in every expression" + }, + "time": { + "type": "number", + "description": "The current time within the composition in seconds", + "notes": "Read only" + }, + "value": { + "type": "Depends on the property", + "description": "The value the property would have without expressions", + "notes": "Read only" + }, + "thisProperty": { + "type": "Property", + "description": "Property the expression is operating on", + "notes": "Read only" + }, + "thisComp": { + "type": "Composition", + "description": "Composition the property is in", + "notes": "Read only" + }, + "thisLayer": { + "type": "Layer", + "description": "Layer the property is in", + "notes": "Read only" + } + }, + "functions": { + "comp": { + "params": [ + { + "name": "name", + "type": "string", + "description": "Composition name" + } + ], + "return": { + "type": "Composition", + "description": "Composition object matching the given name" + } + }, + "posterizeTime": { + "params": [ + { + "name": "fps", + "type": "number", + "description": "Frames per second" + } + ], + "description": "The rest of the expression will only be updated this many times per second" + }, + "timeToFrames": { + "description": "Converts a time in seconds to a number of frames", + "params": [ + { + "name": "time", + "type": "number", + "description": "Time in seconds", + "default": "time + thisComp.displayStartTime" + }, + { + "name": "fps", + "type": "number", + "description": "Frames per second", + "default": "1.0 / thisComp.frameDuration" + } + ], + "return": { + "type": "number", + "description": "Number of frames" + } + }, + "framesToTime": { + "description": "Converts a number of frames to a time in seconds", + "params": [ + { + "name": "frames", + "type": "number", + "description": "Number of frames" + }, + { + "name": "fps", + "type": "number", + "description": "Frames per second", + "default": "1.0 / thisComp.frameDuration" + } + ], + "return": { + "type": "number", + "description": "Time in seconds" + } + }, + "rgbToHsl": { + "params": [ + { + "name": "rgb", + "type": "array[3]|array[4]", + "description": "RGB(A) color, with components in 0, 1" + } + ], + "return": { + "type": "array[3]|array[4]", + "description": "HSL(A) color, with components in 0, 1" + } + }, + "hslToRgb": { + "params": [ + { + "name": "hsl", + "type": "array[3]|array[4]", + "description": "HSL(A) color, with components in 0, 1" + } + ], + "return": { + "type": "array[3]|array[4]", + "description": "RGB(A) color, with components in 0, 1" + } + }, + "createPath": { + "description": "Creates bezier path data", + "params": [ + { + "name": "points", + "type": "array", + "description": "Array of points (each point is a list with 2 numbers)" + }, + { + "name": "in_tangents", + "type": "array", + "description": "Array of in tangents correponding to the point with the same index", + "default": "[]" + }, + { + "name": "out_tangents", + "type": "array", + "description": "Array of out tangents correponding to the point with the same index", + "default": "[]" + }, + { + "name": "is_closed", + "type": "boolean", + "default": "true", + "description": "Whether the path is closed" + } + ], + "return": { + "type": "Path" + } + }, + "add": { + "params": [ + { + "name": "a", + "type": "any", + "description": "" + }, + { + "name": "b", + "type": "any", + "description": "" + } + ], + "return": { + "type": "any", + "description": "" + } + }, + "sub": { + "params": [ + { + "name": "a", + "type": "any", + "description": "" + }, + { + "name": "b", + "type": "any", + "description": "" + } + ], + "return": { + "type": "any", + "description": "" + } + }, + "mul": { + "params": [ + { + "name": "a", + "type": "any", + "description": "" + }, + { + "name": "b", + "type": "any", + "description": "" + } + ], + "return": { + "type": "any", + "description": "" + } + }, + "div": { + "params": [ + { + "name": "a", + "type": "any", + "description": "" + }, + { + "name": "b", + "type": "any", + "description": "" + } + ], + "return": { + "type": "any", + "description": "" + } + }, + "mod": { + "params": [ + { + "name": "a", + "type": "any", + "description": "" + }, + { + "name": "b", + "type": "any", + "description": "" + } + ], + "return": { + "type": "any", + "description": "" + } + }, + "clamp": { + "description": "Clamps a value inside a range", + "params": [ + { + "name": "value", + "type": "number", + "description": "The value to clamp" + }, + { + "name": "minimum", + "type": "number", + "description": "Minimum value" + }, + { + "name": "maximum", + "type": "number", + "description": "Maximum value" + } + ], + "return": { + "type": "number", + "description": "" + } + }, + "normalize": { + "description": "Divides a vector by its length", + "params": [ + { + "name": "vector", + "type": "array" + } + ], + "return": { + "type": "number", + "description": "same as `div(vector, length(vector))`" + } + }, + "length": [ + { + "params": [ + { + "name": "vector", + "type": "array" + } + ], + "return": { + "type": "number", + "description": "length of `vector`" + } + }, + { + "params": [ + { + "name": "a", + "type": "array" + }, + { + "name": "b", + "type": "array" + } + ], + "return": { + "type": "number", + "description": "Distance between `a` and `b`." + } + } + ], + "lookAt": { + "params": [ + { + "name": "from_point", + "type": "array[3]" + }, + { + "name": "to_point", + "type": "array[3]" + } + ], + "return": { + "type": "number", + "description": "length of `vector`" + } + }, + "seedRandom": { + "description": "Sets the seed for random functions", + "params": [ + { + "name": "seed", + "type": "number" + } + ] + }, + "random": [ + { + "return": { + "type": "number", + "description": "Random number between 0 and 1" + } + }, + { + "params": [ + { + "name": "max", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Random number between 0 and `max`, element wise if the argument is an array" + } + }, + { + "params": [ + { + "name": "min", + "type": "number|array" + }, + { + "name": "max", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Random number between `min` and `max`, element wise if the arguments are arrays" + } + } + ], + "linear": [ + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between 0 and 1" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Linear interpolation between `value1` and `value2`" + } + }, + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between `t_min` and `t_max`" + }, + { + "name": "t_min", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "t_max", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Linear interpolation between `value1` and `value2`, `t` is first normalized inside `t_min` and `t_max`" + } + } + ], + "ease": [ + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between 0 and 1" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Interpolation between `value1` and `value2`" + } + }, + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between `t_min` and `t_max`" + }, + { + "name": "t_min", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "t_max", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Interpolation between `value1` and `value2`, `t` is first normalized inside `t_min` and `t_max`" + } + } + ], + "easeIn": [ + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between 0 and 1" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Interpolation between `value1` and `value2`" + } + }, + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between `t_min` and `t_max`" + }, + { + "name": "t_min", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "t_max", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Interpolation between `value1` and `value2`, `t` is first normalized inside `t_min` and `t_max`" + } + } + ], + "easeOut": [ + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between 0 and 1" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Interpolation between `value1` and `value2`" + } + }, + { + "params": [ + { + "name": "t", + "type": "number", + "description": "Interpolation factor between `t_min` and `t_max`" + }, + { + "name": "t_min", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "t_max", + "type": "number", + "description": "Lower bound for the `t` range" + }, + { + "name": "value1", + "type": "number|array" + }, + { + "name": "value2", + "type": "number|array" + } + ], + "return": { + "type": "number|array", + "description": "Interpolation between `value1` and `value2`, `t` is first normalized inside `t_min` and `t_max`" + } + } + ], + "degreesToRadians": { + "params": [ + { + "name": "degrees", + "type": "number", + "description": "Angle in degrees" + } + ], + "return": { + "type": "number", + "description": "Angle in radians" + } + }, + "radiansToDegrees": { + "params": [ + { + "name": "radians", + "type": "number", + "description": "Angle in radians" + } + ], + "return": { + "type": "number", + "description": "Angle in degrees" + } + }, + "footage": {}, + "colorDepth": {}, + "dot": {}, + "cross": {}, + "gaussRandom": {}, + "noise": {} + }, + "aliases": { + "sum": "add", + "$bm_sum": "add", + "$bm_sub": "sub", + "$bm_mul": "mul", + "$bm_div": "div" + } +} diff --git a/schema/expressions.schema.json b/schema/expressions.schema.json new file mode 100644 index 00000000..61fc0c47 --- /dev/null +++ b/schema/expressions.schema.json @@ -0,0 +1,86 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://lottiefiles.github.io/lottie-docs/schema/expressions.schema.json", + "type": "object", + "$defs": { + "variable": { + "type": "object", + "properties": { + "description": {"type": "string"}, + "type": {"$ref": "#/$defs/type"}, + "default": {}, + "notes": {"type": "string"} + }, + "required": ["description", "type"] + }, + "parameter": { + "allOf": [ + { + "$ref": "#/$defs/variable" + }, + { + "type": "object", + "properties": { + "name": {"type": "string"} + }, + "required": ["name"] + } + ] + }, + "function_definition": { + "type": "object", + "properties": { + "return": {"$ref": "#/$defs/variable"}, + "description": {"type": "string"}, + "params": { + "type": "array", + "items": {"$ref": "#/$defs/parameter"} + } + } + }, + "function": { + "oneOf": [ + {"$ref": "#/$defs/function_definition"}, + { + "type": "array", + "items": {"$ref": "#/$defs/function_definition"} + }, + { + "type": "object", + "properties": { + "alias_of": {"type": "string"} + } + } + ] + }, + "type": { + "type": "string", + "bnf": { + "TYPE": "DESCRIPTION | SPECIFIC | OPTIONS", + "OPTIONS": "SPECIFIC | OPTIONS \| SPECIFIC", + "SPECIFIC": "any | number | boolean | string | object | ARRAY", + "ARRAY": "array | array [ NUMBER ]", + "NUMBER": "/[0-9]+/", + "DESCRIPTION": "/.+ .+/" + } + } + }, + "properties": { + "variables": { + "type": "object", + "patternProperties": { + ".+": {"$ref": "#/$defs/variable"} + } + }, + "functions": { + "type": "object", + "patternProperties": { + ".+": {"$ref": "#/$defs/function"} + } + }, + "aliases": { + "type": "object", + "description": "Map alias name to actual function" + } + } +} diff --git a/schema/helpers/bezier.json b/schema/helpers/bezier.json new file mode 100644 index 00000000..a5f43e7c --- /dev/null +++ b/schema/helpers/bezier.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Bezier", + "description": "Single bezier curve", + "properties": { + "c": { + "title": "Closed", + "type": "boolean", + "default": false + }, + "i": { + "title": "In Tangents", + "type": "array", + "description": "Array of points, each point is an array of coordinates.\nThese points are along the `in` tangents relative to the corresponding `v`.", + "items": { + "type": "array", + "items": { + "type": "number", + "default": [] + } + } + }, + "o": { + "title": "Out Tangents", + "type": "array", + "description": "Array of points, each point is an array of coordinates.\nThese points are along the `out` tangents relative to the corresponding `v`.", + "items": { + "type": "array", + "items": { + "type": "number", + "default": [] + } + } + }, + "v": { + "title": "Vertices", + "description": "Array of points, each point is an array of coordinates.\nThese points are along the bezier path", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number", + "default": [] + } + } + } + }, + "required": ["i", "v", "o"] +} diff --git a/schema/helpers/color.json b/schema/helpers/color.json new file mode 100644 index 00000000..2e57784b --- /dev/null +++ b/schema/helpers/color.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "array", + "title": "Color", + "description": "Color as a [r, g, b] array with values in [0, 1]", + "items": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "minItems": 3, + "maxItems": 4 +} diff --git a/schema/helpers/int-boolean.json b/schema/helpers/int-boolean.json new file mode 100644 index 00000000..0f1d0eab --- /dev/null +++ b/schema/helpers/int-boolean.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "integer", + "title": "Integer Boolean", + "description": "Represents boolean values as an integer. 0 is false, 1 is true.", + "default": 0, + "examples": [0], + "enum": [0, 1], + "oneOf": [ + { + "title": "True", + "const": 1 + }, + { + "title": "False", + "const": 0 + } + ] +} diff --git a/schema/helpers/marker.json b/schema/helpers/marker.json new file mode 100644 index 00000000..e9b1fa62 --- /dev/null +++ b/schema/helpers/marker.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Marker", + "description": "Defines named portions of the composition.", + "properties": { + "cm": { + "title": "Comment", + "type": "string" + }, + "tm": { + "title": "Time", + "type": "number" + }, + "dr": { + "title": "Duration", + "type": "number" + } + } +} diff --git a/schema/helpers/mask.json b/schema/helpers/mask.json new file mode 100644 index 00000000..01004a8e --- /dev/null +++ b/schema/helpers/mask.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Mask", + "caniuse": "mask", + "description": "Bezier shape used to mask/clip a layer", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "inv": { + "title": "Inverted", + "caniuse": "mask-inverted", + "type": "boolean", + "default": false + }, + "pt": { + "title": "Shape", + "$ref": "#/$defs/animated-properties/shape-property" + }, + "o": { + "title": "Opacity", + "caniuse": "mask-opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "mode": { + "title": "Mode", + "caniuse": "mask-modes", + "$ref": "#/$defs/constants/mask-mode", + "default": "i" + }, + "x": { + "title": "Expand", + "caniuse": "mask-expansion", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] +} diff --git a/schema/helpers/transform.json b/schema/helpers/transform.json new file mode 100644 index 00000000..e4edc90d --- /dev/null +++ b/schema/helpers/transform.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Transform", + "description": "Layer transform", + "allOf": [ + { + "properties": { + "a": { + "title": "Anchor Point", + "caniuse": "transform-anchor-point", + "description": "Anchor point: a position (relative to its parent) around which transformations are applied (ie: center for rotation / scale)", + "$ref": "#/$defs/animated-properties/position" + }, + "s": { + "title": "Scale", + "caniuse": "transform-scale", + "description": "Scale factor, `[100, 100]` for no scaling", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "o": { + "title": "Opacity", + "caniuse": "transform-opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "sk": { + "title": "Skew", + "caniuse": "transform-skew", + "description": "Skew amount as an angle in degrees", + "$ref": "#/$defs/animated-properties/value" + }, + "sa": { + "title": "Skew Axis", + "caniuse": "transform-skew", + "description": "Direction along which skew is applied, in degrees (`0` skews along the X axis, `90` along the Y axis)", + "$ref": "#/$defs/animated-properties/value" + } + } + }, + { + "anyOf": [ + { + "oneOf": [ + { + "properties": { + "p": { + "title": "Position", + "caniuse": "transform-position", + "description": "Position / Translation", + "$ref": "#/$defs/animated-properties/position" + } + } + }, + { + "properties": { + "p": { + "title": "Position", + "description": "Position / Translation with split components", + "$ref": "#/$defs/animated-properties/split-vector" + } + } + } + ] + }, + { + "oneOf": [ + { + "properties": { + "r": { + "title": "Rotation", + "caniuse": "transform-rotation", + "description": "Rotation in degrees, clockwise", + "$ref": "#/$defs/animated-properties/value" + } + } + }, + { + "properties": { + "rx": { + "title": "X Rotation", + "description": "Split rotation component", + "$ref": "#/$defs/animated-properties/value" + }, + "ry": { + "title": "Y Rotation", + "description": "Split rotation component", + "$ref": "#/$defs/animated-properties/value" + }, + "rz": { + "title": "Z Rotation", + "description": "Split rotation component, equivalent to `r` when not split", + "$ref": "#/$defs/animated-properties/value" + }, + "or": { + "title": "Orientation", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + } + } + ] + } + ] + } + ] +} diff --git a/schema/helpers/visual-object.json b/schema/helpers/visual-object.json new file mode 100644 index 00000000..50361764 --- /dev/null +++ b/schema/helpers/visual-object.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Visual Object", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "nm": { + "title": "Name", + "description": "Name, as seen from editors and the like", + "type": "string" + }, + "mn": { + "title": "Match Name", + "description": "Match name, used in expressions", + "type": "string" + } + }, + "required": [] + } + ] +} diff --git a/schema/index.html b/schema/index.html new file mode 100644 index 00000000..d08cb65a --- /dev/null +++ b/schema/index.html @@ -0,0 +1,6298 @@ + + + + + + + + + + + + + + JSON Schema - Lottie Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

JSON Schema

+

This page shows a formatted version of the JSON schema, you can click on highlighted +objects to get a link to that section of the schema. You can also click on $ref +values to jump to the relevant section.

+

If you want you can also view the raw schema file.

+

+

{
+    "$schema": "https://json-schema.org/draft/2020-12/schema",
+    "$id": "https://lottiefiles.github.io/lottie-docs/schema/lottie.schema.json",
+    "type": "object",
+    "allOf": [
+        {
+            "$ref": "#/$defs/animation/animation"
+        }
+    ],
+    "$defs": {
+        "animated-properties": {
+            "color-value"    : {
+                "type": "object",
+                "title": "Color Value",
+                "description": "An animatable property that holds a Color",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/animated-properties/animated-property"
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "a": {
+                                    "const": 0
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "k": {
+                                    "title": "Static value",
+                                    "$ref": "#/$defs/helpers/color"
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "shape-keyframe"  : {
+                "type": "object",
+                "title": "Shape Keyframe",
+                "description": "Keyframe holding Bezier objects",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/animated-properties/keyframe-base"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "s": {
+                                "title": "Start",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/helpers/bezier"
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "position-keyframe"  : {
+                "type": "object",
+                "title": "Position Keyframe",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/animated-properties/keyframe"
+                    },
+                    {
+                        "properties": {
+                            "ti": {
+                                "title": "Value In Tangent",
+                                "description": "Tangent for values (eg: moving position around a curved path)",
+                                "type": "array",
+                                "items": {
+                                    "type": "number"
+                                }
+                            },
+                            "to": {
+                                "title": "Value Out Tangent",
+                                "description": "Tangent for values (eg: moving position around a curved path)",
+                                "type": "array",
+                                "items": {
+                                    "type": "number"
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "keyframe-bezier-handle"  : {
+                "type": "object",
+                "title": "Keyframe Bezier Handle",
+                "description": "Bezier handle for keyframe interpolation",
+                "properties": {
+                    "x": {
+                        "title": "X",
+                        "description": "Time component:\n0 means start time of the keyframe,\n1 means time of the next keyframe.",
+                        "oneOf": [
+                            {
+                                "type": "array",
+                                "items": {
+                                    "type": "number",
+                                    "default": 0,
+                                    "minimum": 0,
+                                    "maximum": 1
+                                },
+                                "minItems": 1
+                            },
+                            {
+                                "type": "number",
+                                "default": 0,
+                                "minimum": 0,
+                                "maximum": 1
+                            }
+                        ]
+                    },
+                    "y": {
+                        "title": "Y",
+                        "description": "Value interpolation component:\n0 means start value of the keyframe,\n1 means value at the next keyframe.",
+                        "oneOf": [
+                            {
+                                "type": "array",
+                                "items": {
+                                    "type": "number",
+                                    "default": 0,
+                                    "minimum": 0,
+                                    "maximum": 1
+                                },
+                                "minItems": 1
+                            },
+                            {
+                                "type": "number",
+                                "default": 0,
+                                "minimum": 0,
+                                "maximum": 1
+                            }
+                        ]
+                    }
+                },
+                "required": [
+                    "x",
+                    "y"
+                ]
+            },
+            "animated-property"  : {
+                "type": "object",
+                "title": "Animated Property",
+                "description": "An animatable property that holds an array of numbers",
+                "allOf": [
+                    {
+                        "properties": {
+                            "ix": {
+                                "title": "Property Index",
+                                "type": "integer"
+                            },
+                            "a": {
+                                "title": "Animated",
+                                "description": "Whether the property is animated",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            },
+                            "x": {
+                                "title": "Expression",
+                                "type": "string"
+                            },
+                            "sid": {
+                                "title": "Slot ID",
+                                "description": "One of the ID in the file's slots",
+                                "type": "string"
+                            }
+                        }
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "a": {
+                                    "const": 1
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "k": {
+                                    "type": "array",
+                                    "title": "Animated Value",
+                                    "description": "Array of keyframes",
+                                    "items": {
+                                        "$ref": "#/$defs/animated-properties/keyframe"
+                                    }
+                                }
+                            }
+                        }
+                    }
+                ],
+                "required": [
+                    "k"
+                ]
+            },
+            "multi-dimensional"  : {
+                "type": "object",
+                "title": "Multi Dimensional",
+                "description": "An animatable property that holds an array of numbers",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/animated-properties/animated-property"
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "a": {
+                                    "const": 0
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "k": {
+                                    "title": "Static value",
+                                    "type": "array",
+                                    "items": {
+                                        "type": "number"
+                                    }
+                                }
+                            }
+                        },
+                        "properties": {
+                            "l": {
+                                "title": "Length",
+                                "description": "Number of components in the value arrays.\nIf present values will be truncated or expanded to match this length when accessed from expressions.",
+                                "type": "integer"
+                            }
+                        }
+                    }
+                ]
+            },
+            "value"  : {
+                "type": "object",
+                "title": "Value",
+                "description": "An animatable property that holds a float",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/animated-properties/animated-property"
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "a": {
+                                    "const": 0
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "k": {
+                                    "title": "Static value",
+                                    "type": "number"
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "gradient-colors"  : {
+                "type": "object",
+                "title": "Gradient Colors",
+                "description": "Represents colors and offsets in a gradient\n\nColors are represented as a flat list interleaving offsets and color components in weird ways\nThere are two possible layouts:\n\nWithout alpha, the colors are a sequence of offset, r, g, b\n\nWith alpha, same as above but at the end of the list there is a sequence of offset, alpha",
+                "properties": {
+                    "k": {
+                        "title": "Colors",
+                        "$ref": "#/$defs/animated-properties/multi-dimensional"
+                    },
+                    "p": {
+                        "title": "Count",
+                        "description": "Number of colors in k",
+                        "type": "integer",
+                        "default": 0
+                    }
+                },
+                "required": [
+                    "p",
+                    "k"
+                ]
+            },
+            "keyframe"  : {
+                "type": "object",
+                "title": "Keyframe",
+                "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/animated-properties/keyframe-base"
+                    },
+                    {
+                        "properties": {
+                            "s": {
+                                "title": "Value",
+                                "description": "Value at this keyframe. Note the if the property is a scalar, keyframe values are still represented as arrays",
+                                "type": "array",
+                                "items": {
+                                    "type": "number"
+                                }
+                            },
+                            "e": {
+                                "title": "End value",
+                                "description": "Value at the end of the keyframe, note that this is deprecated and you should use s from the next keyframe to get this value",
+                                "deprecated": true,
+                                "type": "array",
+                                "items": {
+                                    "type": "number"
+                                }
+                            }
+                        }
+                    },
+                    {
+                        "if": {
+                            "oneOf": [
+                                {
+                                    "properties": {
+                                        "h": {
+                                            "const": 0
+                                        }
+                                    }
+                                },
+                                {
+                                    "not": {
+                                        "required": [
+                                            "h"
+                                        ]
+                                    }
+                                }
+                            ]
+                        },
+                        "then": {
+                            "properties": {
+                                "i": {
+                                    "title": "In Tangent",
+                                    "description": "Easing tangent going into the next keyframe",
+                                    "$ref": "#/$defs/animated-properties/keyframe-bezier-handle"
+                                },
+                                "o": {
+                                    "title": "Out Tangent",
+                                    "description": "Easing tangent leaving the current keyframe",
+                                    "$ref": "#/$defs/animated-properties/keyframe-bezier-handle"
+                                }
+                            }
+                        }
+                    }
+                ],
+                "required": [
+                    "t",
+                    "s"
+                ]
+            },
+            "position"  : {
+                "type": "object",
+                "title": "Position Property",
+                "description": "An animatable property to represent a position in space",
+                "allOf": [
+                    {
+                        "properties": {
+                            "ix": {
+                                "title": "Property Index",
+                                "type": "integer"
+                            },
+                            "a": {
+                                "title": "Animated",
+                                "description": "Whether the property is animated",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            },
+                            "x": {
+                                "title": "Expression",
+                                "type": "string"
+                            },
+                            "l": {
+                                "title": "Length",
+                                "description": "Number of components in the value arrays.\nIf present values will be truncated or expanded to match this length when accessed from expressions.",
+                                "type": "integer"
+                            }
+                        }
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "a": {
+                                    "const": 1
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "k": {
+                                    "type": "array",
+                                    "title": "Animated Value",
+                                    "description": "Array of keyframes",
+                                    "items": {
+                                        "$ref": "#/$defs/animated-properties/position-keyframe"
+                                    }
+                                }
+                            }
+                        },
+                        "else": {
+                            "properties": {
+                                "k": {
+                                    "title": "Static Value",
+                                    "type": "array",
+                                    "items": {
+                                        "type": "number"
+                                    }
+                                }
+                            }
+                        }
+                    }
+                ],
+                "required": [
+                    "k"
+                ]
+            },
+            "shape-property"    : {
+                "type": "object",
+                "title": "Shape Property",
+                "description": "An animatable property that holds a Bezier",
+                "allOf": [
+                    {
+                        "properties": {
+                            "ix": {
+                                "title": "Property Index",
+                                "type": "integer"
+                            },
+                            "a": {
+                                "title": "Animated",
+                                "description": "Whether the property is animated",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            },
+                            "x": {
+                                "title": "Expression",
+                                "type": "string"
+                            }
+                        }
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "a": {
+                                    "const": 1
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "k": {
+                                    "type": "array",
+                                    "title": "Animated Value",
+                                    "description": "Array of keyframes",
+                                    "items": {
+                                        "$ref": "#/$defs/animated-properties/shape-keyframe"
+                                    }
+                                }
+                            }
+                        },
+                        "else": {
+                            "properties": {
+                                "k": {
+                                    "$ref": "#/$defs/helpers/bezier",
+                                    "title": "Static Value"
+                                }
+                            }
+                        }
+                    }
+                ],
+                "required": [
+                    "k"
+                ]
+            },
+            "keyframe-base"  : {
+                "type": "object",
+                "title": "Base Keyframe",
+                "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.",
+                "allOf": [
+                    {
+                        "properties": {
+                            "t": {
+                                "title": "Time",
+                                "type": "number",
+                                "default": 0
+                            },
+                            "h": {
+                                "title": "Hold",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            }
+                        }
+                    },
+                    {
+                        "if": {
+                            "oneOf": [
+                                {
+                                    "properties": {
+                                        "h": {
+                                            "const": 0
+                                        }
+                                    }
+                                },
+                                {
+                                    "not": {
+                                        "required": [
+                                            "h"
+                                        ]
+                                    }
+                                }
+                            ]
+                        },
+                        "then": {
+                            "properties": {
+                                "i": {
+                                    "title": "In Tangent",
+                                    "description": "Easing tangent going into the next keyframe",
+                                    "$ref": "#/$defs/animated-properties/keyframe-bezier-handle"
+                                },
+                                "o": {
+                                    "title": "Out Tangent",
+                                    "description": "Easing tangent leaving the current keyframe",
+                                    "$ref": "#/$defs/animated-properties/keyframe-bezier-handle"
+                                }
+                            }
+                        }
+                    }
+                ],
+                "required": [
+                    "t",
+                    "s"
+                ]
+            },
+            "split-vector"  : {
+                "type": "object",
+                "title": "Split Vector",
+                "description": "An animatable property that is split into individually anaimated components",
+                "properties": {
+                    "s": {
+                        "title": "Split",
+                        "type": "boolean",
+                        "const": true
+                    },
+                    "x": {
+                        "title": "X",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "y": {
+                        "title": "Y",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "z": {
+                        "title": "Z",
+                        "$ref": "#/$defs/animated-properties/value"
+                    }
+                },
+                "required": [
+                    "s",
+                    "x",
+                    "y"
+                ]
+            }
+        },
+        "animation": {
+            "motion-blur"  : {
+                "type": "object",
+                "title": "Motion Blur",
+                "description": "Motion blur settings",
+                "properties": {
+                    "sa": {
+                        "title": "Shutter Angle",
+                        "description": "Angle in degrees",
+                        "type": "number"
+                    },
+                    "sp": {
+                        "title": "Shutter Phase",
+                        "description": "Angle in degrees",
+                        "type": "number"
+                    },
+                    "spf": {
+                        "title": "Samples per Frame",
+                        "type": "number"
+                    },
+                    "asl": {
+                        "title": "Adaptive Sample Limit",
+                        "type": "number"
+                    }
+                }
+            },
+            "animation"  : {
+                "type": "object",
+                "title": "Animation",
+                "description": "Top level object, describing the animation",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "v": {
+                                "title": "Version",
+                                "type": "string",
+                                "default": "5.5.2"
+                            },
+                            "fr": {
+                                "title": "Framerate",
+                                "description": "Framerate in frames per second",
+                                "type": "number",
+                                "default": 60
+                            },
+                            "ip": {
+                                "title": "In Point",
+                                "description": "\"In Point\", which frame the animation starts at (usually 0)",
+                                "type": "number",
+                                "default": 0
+                            },
+                            "op": {
+                                "title": "Out Point",
+                                "description": "\"Out Point\", which frame the animation stops/loops at, which makes this the duration in frames when ip is 0",
+                                "type": "number",
+                                "default": 60
+                            },
+                            "w": {
+                                "title": "Width",
+                                "description": "Width of the animation",
+                                "type": "integer",
+                                "default": 512
+                            },
+                            "h": {
+                                "title": "Height",
+                                "description": "Height of the animation",
+                                "type": "integer",
+                                "default": 512
+                            },
+                            "ddd": {
+                                "title": "Threedimensional",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0,
+                                "description": "Whether the animation has 3D layers"
+                            },
+                            "assets": {
+                                "title": "Assets",
+                                "type": "array",
+                                "description": "List of assets that can be referenced by layers",
+                                "items": {
+                                    "oneOf": [
+                                        {
+                                            "$ref": "#/$defs/assets/image"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/assets/precomposition"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/assets/sound"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/assets/data-source"
+                                        }
+                                    ]
+                                }
+                            },
+                            "comps": {
+                                "title": "Extra Compositions",
+                                "type": "array",
+                                "description": "List of Extra compositions not referenced by anything",
+                                "items": {
+                                    "$ref": "#/$defs/assets/precomposition"
+                                }
+                            },
+                            "fonts": {
+                                "title": "Fonts",
+                                "$ref": "#/$defs/text/font-list"
+                            },
+                            "chars": {
+                                "title": "Characters",
+                                "description": "Data defining text characters as lottie shapes. If present a player might only render characters defined here and nothing else.",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/text/character-data"
+                                }
+                            },
+                            "meta": {
+                                "title": "Metadata",
+                                "description": "Document metadata",
+                                "$ref": "#/$defs/animation/metadata"
+                            },
+                            "metadata": {
+                                "title": "User Metadata",
+                                "$ref": "#/$defs/animation/user-metadata"
+                            },
+                            "markers": {
+                                "title": "Markers",
+                                "description": "Markers defining named sections of the composition.",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/helpers/marker"
+                                }
+                            },
+                            "mb": {
+                                "title": "Motion Blur",
+                                "$ref": "#/$defs/animation/motion-blur"
+                            },
+                            "slots": {
+                                "title": "Slots",
+                                "description": "Available property overrides",
+                                "type": "object",
+                                "patternProperties": {
+                                    ".*": {
+                                        "p": {
+                                            "anyOf": [
+                                                {
+                                                    "$ref": "#/$defs/animated-properties/multi-dimensional"
+                                                },
+                                                {
+                                                    "$ref": "#/$defs/animated-properties/color-value"
+                                                },
+                                                {
+                                                    "$ref": "#/$defs/animated-properties/position"
+                                                },
+                                                {
+                                                    "$ref": "#/$defs/animated-properties/shape-property"
+                                                },
+                                                {
+                                                    "$ref": "#/$defs/animated-properties/value"
+                                                },
+                                                {
+                                                    "$ref": "#/$defs/assets/image"
+                                                },
+                                                {
+                                                    "$ref": "#/$defs/text/animated-text-document"
+                                                }
+                                            ]
+                                        },
+                                        "required": [
+                                            "p"
+                                        ]
+                                    }
+                                }
+                            }
+                        },
+                        "required": [
+                            "w",
+                            "h",
+                            "fr",
+                            "layers",
+                            "op",
+                            "ip"
+                        ]
+                    },
+                    {
+                        "$ref": "#/$defs/animation/composition"
+                    }
+                ]
+            },
+            "composition"  : {
+                "type": "object",
+                "title": "Composition",
+                "description": "Base class for layer holders",
+                "properties": {
+                    "layers": {
+                        "title": "Layers",
+                        "type": "array",
+                        "items": {
+                            "oneOf": [
+                                {
+                                    "$ref": "#/$defs/layers/precomposition-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/solid-color-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/image-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/null-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/shape-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/text-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/audio-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/camera-layer"
+                                },
+                                {
+                                    "$ref": "#/$defs/layers/data-layer"
+                                }
+                            ]
+                        }
+                    }
+                },
+                "required": [
+                    "layers"
+                ]
+            },
+            "user-metadata"  : {
+                "type": "object",
+                "title": "User Metadata",
+                "description": "User-defined metadata",
+                "properties": {
+                    "filename": {
+                        "title": "Filename",
+                        "type": "string"
+                    },
+                    "customProps": {
+                        "title": "Custom Properties",
+                        "type": "object"
+                    }
+                }
+            },
+            "metadata"  : {
+                "type": "object",
+                "title": "Metadata",
+                "description": "Document metadata",
+                "properties": {
+                    "a": {
+                        "title": "Author",
+                        "type": "string"
+                    },
+                    "d": {
+                        "title": "Description",
+                        "type": "string"
+                    },
+                    "tc": {
+                        "title": "Theme Color",
+                        "type": "string"
+                    },
+                    "g": {
+                        "title": "Generator",
+                        "description": "Software used to generate the file",
+                        "type": "string"
+                    }
+                },
+                "anyOf": [
+                    {
+                        "properties": {
+                            "k": {
+                                "title": "Keywords",
+                                "type": "array",
+                                "items": {
+                                    "type": "string"
+                                }
+                            }
+                        }
+                    },
+                    {
+                        "properties": {
+                            "k": {
+                                "title": "Keywords",
+                                "type": "string"
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        "assets": {
+            "data-source"  : {
+                "type": "object",
+                "title": "Data source",
+                "description": "External data source, usually a JSON file",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/assets/file-asset"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "t": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 3
+                            }
+                        },
+                        "required": [
+                            "t"
+                        ]
+                    }
+                ]
+            },
+            "sound"  : {
+                "type": "object",
+                "title": "Sound",
+                "description": "External sound",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/assets/file-asset"
+                    }
+                ]
+            },
+            "image"  : {
+                "type": "object",
+                "title": "Image",
+                "description": "External image",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/assets/file-asset"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "w": {
+                                "title": "Width",
+                                "description": "Width of the image",
+                                "type": "number",
+                                "default": 0
+                            },
+                            "h": {
+                                "title": "Height",
+                                "description": "Height of the image",
+                                "type": "number",
+                                "default": 0
+                            },
+                            "t": {
+                                "title": "Type",
+                                "description": "Marks as part of an image sequence if present",
+                                "type": "string",
+                                "const": "seq"
+                            },
+                            "sid": {
+                                "title": "Slot ID",
+                                "description": "One of the ID in the file's slots",
+                                "type": "string"
+                            }
+                        },
+                        "required": [
+                            "p"
+                        ]
+                    }
+                ]
+            },
+            "file-asset"  : {
+                "type": "object",
+                "title": "File Asset",
+                "description": "Asset referencing a file",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/assets/asset"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "u": {
+                                "title": "Path",
+                                "description": "Path to the directory containing a file",
+                                "type": "string",
+                                "default": ""
+                            },
+                            "p": {
+                                "title": "File name",
+                                "description": "Filename or data url",
+                                "type": "string",
+                                "default": ""
+                            },
+                            "e": {
+                                "title": "Embedded",
+                                "description": "Whether the file is embedded",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            }
+                        },
+                        "required": [
+                            "p"
+                        ]
+                    }
+                ]
+            },
+            "asset"  : {
+                "type": "object",
+                "title": "Asset",
+                "description": "",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "id": {
+                                "title": "ID",
+                                "description": "Unique identifier used by layers when referencing this asset",
+                                "type": "string",
+                                "default": ""
+                            },
+                            "nm": {
+                                "title": "Name",
+                                "description": "Human readable name",
+                                "type": "string"
+                            }
+                        },
+                        "required": [
+                            "id"
+                        ]
+                    }
+                ]
+            },
+            "precomposition"  : {
+                "type": "object",
+                "title": "Precomposition",
+                "description": "Asset containing an animation that can be referenced by layers.",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/assets/asset"
+                    },
+                    {
+                        "$ref": "#/$defs/animation/composition"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "fr": {
+                                "title": "Framerate",
+                                "description": "Framerate in frames per second",
+                                "type": "number"
+                            },
+                            "xt": {
+                                "title": "Extra",
+                                "description": "Extra composition",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        "constants": {
+            "trim-multiple-shapes"  : {
+                "type": "integer",
+                "title": "Trim Multiple Shapes",
+                "description": "How to handle multiple shapes in trim path",
+                "oneOf": [
+                    {
+                        "title": "Simultaneously",
+                        "const": 1
+                    },
+                    {
+                        "title": "Individually",
+                        "const": 2
+                    }
+                ]
+            },
+            "stroke-dash-type"  : {
+                "type": "string",
+                "title": "Stroke Dash Type",
+                "description": "Type of a dash item in a stroked line",
+                "oneOf": [
+                    {
+                        "title": "Dash",
+                        "const": "d"
+                    },
+                    {
+                        "title": "Gap",
+                        "const": "g"
+                    },
+                    {
+                        "title": "Offset",
+                        "const": "o"
+                    }
+                ]
+            },
+            "shape-direction"  : {
+                "type": "integer",
+                "title": "Shape Direction",
+                "description": "Drawing direction of the shape curve, useful for trim path",
+                "oneOf": [
+                    {
+                        "title": "Normal",
+                        "description": "Usually clockwise",
+                        "const": 1
+                    },
+                    {
+                        "title": "Reversed",
+                        "description": "Usually counter clockwise",
+                        "const": 3
+                    }
+                ]
+            },
+            "text-shape"  : {
+                "type": "integer",
+                "title": "Text Shape",
+                "description": "Defines the function used to determine the interpolating factor on a text range selector.",
+                "oneOf": [
+                    {
+                        "title": "Square",
+                        "const": 1
+                    },
+                    {
+                        "title": "Ramp Up",
+                        "const": 2
+                    },
+                    {
+                        "title": "Ramp Down",
+                        "const": 3
+                    },
+                    {
+                        "title": "Triangle",
+                        "const": 4
+                    },
+                    {
+                        "title": "Round",
+                        "const": 5
+                    },
+                    {
+                        "title": "Smooth",
+                        "const": 6
+                    }
+                ]
+            },
+            "text-range-units"  : {
+                "type": "integer",
+                "title": "Text Range Units",
+                "description": "Unit type for a text selector",
+                "oneOf": [
+                    {
+                        "title": "Percent",
+                        "const": 1
+                    },
+                    {
+                        "title": "Index",
+                        "const": 2
+                    }
+                ]
+            },
+            "text-grouping"  : {
+                "type": "integer",
+                "title": "Text Grouping",
+                "description": "",
+                "oneOf": [
+                    {
+                        "title": "Characters",
+                        "const": 1
+                    },
+                    {
+                        "title": "Word",
+                        "const": 2
+                    },
+                    {
+                        "title": "Line",
+                        "const": 3
+                    },
+                    {
+                        "title": "All",
+                        "const": 4
+                    }
+                ]
+            },
+            "composite"  : {
+                "type": "integer",
+                "title": "Composite",
+                "description": "How to stack copies in a repeater",
+                "oneOf": [
+                    {
+                        "title": "Below",
+                        "description": "Subsequent copies are added underneath the previous ones.",
+                        "const": 1
+                    },
+                    {
+                        "title": "Above",
+                        "description": "Subsequent copies are added on top of the previous ones.",
+                        "const": 2
+                    }
+                ]
+            },
+            "mask-mode"  : {
+                "type": "string",
+                "title": "Mask Mode",
+                "description": "How masks interact with each other. See https://helpx.adobe.com/after-effects/using/alpha-channels-masks-mattes.html",
+                "oneOf": [
+                    {
+                        "title": "None",
+                        "const": "n"
+                    },
+                    {
+                        "title": "Add",
+                        "const": "a"
+                    },
+                    {
+                        "title": "Subtract",
+                        "const": "s"
+                    },
+                    {
+                        "title": "Intersect",
+                        "const": "i"
+                    },
+                    {
+                        "title": "Lighten",
+                        "const": "l"
+                    },
+                    {
+                        "title": "Darken",
+                        "const": "d"
+                    },
+                    {
+                        "title": "Difference",
+                        "const": "f"
+                    }
+                ]
+            },
+            "line-join"  : {
+                "type": "integer",
+                "title": "Line Join",
+                "description": "Style at a sharp corner of a stoked line",
+                "oneOf": [
+                    {
+                        "title": "Miter",
+                        "const": 1
+                    },
+                    {
+                        "title": "Round",
+                        "const": 2
+                    },
+                    {
+                        "title": "Bevel",
+                        "const": 3
+                    }
+                ]
+            },
+            "font-path-origin"  : {
+                "type": "integer",
+                "title": "Font Path Origin",
+                "description": "",
+                "oneOf": [
+                    {
+                        "title": "Local",
+                        "const": 0
+                    },
+                    {
+                        "title": "Css Url",
+                        "const": 1
+                    },
+                    {
+                        "title": "Script Url",
+                        "const": 2
+                    },
+                    {
+                        "title": "Font Url",
+                        "const": 3
+                    }
+                ]
+            },
+            "line-cap"  : {
+                "type": "integer",
+                "title": "Line Cap",
+                "description": "Style at the end of a stoked line",
+                "oneOf": [
+                    {
+                        "title": "Butt",
+                        "const": 1
+                    },
+                    {
+                        "title": "Round",
+                        "const": 2
+                    },
+                    {
+                        "title": "Square",
+                        "const": 3
+                    }
+                ]
+            },
+            "gradient-type"  : {
+                "type": "integer",
+                "title": "Gradient Type",
+                "description": "Type of a gradient",
+                "oneOf": [
+                    {
+                        "title": "Linear",
+                        "type": "integer",
+                        "const": 1
+                    },
+                    {
+                        "title": "Radial",
+                        "type": "integer",
+                        "const": 2
+                    }
+                ]
+            },
+            "merge-mode"  : {
+                "type": "integer",
+                "title": "Merge Mode",
+                "description": "Boolean operation on shapes",
+                "oneOf": [
+                    {
+                        "title": "Normal",
+                        "const": 1
+                    },
+                    {
+                        "title": "Add",
+                        "const": 2
+                    },
+                    {
+                        "title": "Subtract",
+                        "const": 3
+                    },
+                    {
+                        "title": "Intersect",
+                        "const": 4
+                    },
+                    {
+                        "title": "Exclude Intersections",
+                        "const": 5
+                    }
+                ]
+            },
+            "fill-rule"  : {
+                "type": "integer",
+                "title": "Fill Rule",
+                "description": "Rule used to handle multiple shapes rendered with the same fill object",
+                "oneOf": [
+                    {
+                        "title": "Non Zero",
+                        "description": "Everything is colored (You can think of this as an OR)",
+                        "const": 1
+                    },
+                    {
+                        "title": "Even Odd",
+                        "description": "Colored based on intersections and path direction, can be used to create \"holes\"",
+                        "const": 2
+                    }
+                ]
+            },
+            "text-caps"  : {
+                "type": "integer",
+                "title": "Text Caps",
+                "oneOf": [
+                    {
+                        "title": "Regular",
+                        "const": 0
+                    },
+                    {
+                        "title": "All Caps",
+                        "const": 1
+                    },
+                    {
+                        "title": "Small Caps",
+                        "const": 2
+                    }
+                ],
+                "default": 0
+            },
+            "blend-mode"  : {
+                "type": "integer",
+                "title": "Blend Mode",
+                "description": "Layer and shape blend mode",
+                "caniuse": "blend-mode",
+                "oneOf": [
+                    {
+                        "title": "Normal",
+                        "const": 0
+                    },
+                    {
+                        "title": "Multiply",
+                        "const": 1
+                    },
+                    {
+                        "title": "Screen",
+                        "const": 2
+                    },
+                    {
+                        "title": "Overlay",
+                        "const": 3
+                    },
+                    {
+                        "title": "Darken",
+                        "const": 4
+                    },
+                    {
+                        "title": "Lighten",
+                        "const": 5
+                    },
+                    {
+                        "title": "Color Dodge",
+                        "const": 6
+                    },
+                    {
+                        "title": "Color Burn",
+                        "const": 7
+                    },
+                    {
+                        "title": "Hard Light",
+                        "const": 8
+                    },
+                    {
+                        "title": "Soft Light",
+                        "const": 9
+                    },
+                    {
+                        "title": "Difference",
+                        "const": 10
+                    },
+                    {
+                        "title": "Exclusion",
+                        "const": 11
+                    },
+                    {
+                        "title": "Hue",
+                        "const": 12
+                    },
+                    {
+                        "title": "Saturation",
+                        "const": 13
+                    },
+                    {
+                        "title": "Color",
+                        "const": 14
+                    },
+                    {
+                        "title": "Luminosity",
+                        "const": 15
+                    },
+                    {
+                        "title": "Add",
+                        "const": 16
+                    },
+                    {
+                        "title": "Hard Mix",
+                        "const": 17
+                    }
+                ]
+            },
+            "text-justify"  : {
+                "type": "integer",
+                "title": "Text Justify",
+                "description": "Text alignment / justification",
+                "oneOf": [
+                    {
+                        "title": "Left",
+                        "const": 0
+                    },
+                    {
+                        "title": "Right",
+                        "const": 1
+                    },
+                    {
+                        "title": "Center",
+                        "const": 2
+                    },
+                    {
+                        "title": "Justify with Last Line Left",
+                        "const": 3
+                    },
+                    {
+                        "title": "Justify with Last Line Right",
+                        "const": 4
+                    },
+                    {
+                        "title": "Justify with Last Line Center",
+                        "const": 5
+                    },
+                    {
+                        "title": "Justify with Last Line Full",
+                        "const": 6
+                    }
+                ]
+            },
+            "matte-mode"  : {
+                "type": "integer",
+                "title": "Matte Mode",
+                "description": "How a layer should mask another layer",
+                "oneOf": [
+                    {
+                        "title": "Normal",
+                        "const": 0
+                    },
+                    {
+                        "title": "Alpha",
+                        "const": 1
+                    },
+                    {
+                        "title": "Inverted Alpha",
+                        "const": 2
+                    },
+                    {
+                        "title": "Luma",
+                        "const": 3
+                    },
+                    {
+                        "title": "Inverted Luma",
+                        "const": 4
+                    }
+                ]
+            },
+            "text-based"  : {
+                "type": "integer",
+                "title": "Text Based",
+                "description": "",
+                "oneOf": [
+                    {
+                        "title": "Characters",
+                        "const": 1
+                    },
+                    {
+                        "title": "Character Excluding Spaces",
+                        "const": 2
+                    },
+                    {
+                        "title": "Words",
+                        "const": 3
+                    },
+                    {
+                        "title": "Lines",
+                        "const": 4
+                    }
+                ]
+            },
+            "star-type"  : {
+                "type": "integer",
+                "title": "Star Type",
+                "description": "Star or Polygon",
+                "oneOf": [
+                    {
+                        "title": "Star",
+                        "const": 1
+                    },
+                    {
+                        "title": "Polygon",
+                        "const": 2
+                    }
+                ]
+            }
+        },
+        "effect-values": {
+            "checkbox"  : {
+                "type": "object",
+                "title": "Effect Value Checkbox",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 4
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "angle"  : {
+                "type": "object",
+                "title": "Effect Value Angle",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 1
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "drop-down"  : {
+                "type": "object",
+                "title": "Effect Value Drop Down",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 7
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "slider"  : {
+                "type": "object",
+                "title": "Effect Value Slider",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 0
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "point"  : {
+                "type": "object",
+                "title": "Effect Value Point",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 3
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "ignored"  : {
+                "type": "object",
+                "title": "Ignored Value",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 6
+                            },
+                            "v": {
+                                "title": "Value",
+                                "type": "number",
+                                "default": 0
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "no-value"  : {
+                "type": "object",
+                "title": "Effect No Value",
+                "description": ""
+            },
+            "effect-value"  : {
+                "type": "object",
+                "title": "Effect Value",
+                "description": "Value for an effect",
+                "caniuse": "effects",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ix": {
+                                "title": "Effect Index",
+                                "type": "integer"
+                            },
+                            "mn": {
+                                "title": "Match Name",
+                                "type": "string"
+                            },
+                            "nm": {
+                                "title": "Name",
+                                "type": "string"
+                            },
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "color"  : {
+                "type": "object",
+                "title": "Effect Value Color",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 2
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "layer"  : {
+                "type": "object",
+                "title": "Effect Value Layer",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effect-values/effect-value"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 10
+                            },
+                            "v": {
+                                "title": "Value",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            }
+        },
+        "effects": {
+            "gaussian-blur-effect"  : {
+                "type": "object",
+                "title": "Gaussian Blur Effect",
+                "description": "Gaussian blur",
+                "caniuse": "effect-gaussian-blur",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 29
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "sigma",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "direction",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "wrap",
+                                        "$ref": "#/$defs/effect-values/checkbox"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "drop-shadow-effect"  : {
+                "type": "object",
+                "title": "Drop Shadow Effect",
+                "description": "Adds a shadow to the layer",
+                "caniuse": "effect-drop-shadow",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 25
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "color",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "opacity",
+                                        "description": "Opacity between 0 and 255",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "angle",
+                                        "$ref": "#/$defs/effect-values/angle"
+                                    },
+                                    {
+                                        "title": "distance",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "blur",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "tint-effect"  : {
+                "type": "object",
+                "title": "Tint Effect",
+                "description": "Colorizes the layer",
+                "caniuse": "effect-tint",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 20
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Black Color",
+                                        "description": "Tint of the darker parts of the layer",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "White Color",
+                                        "description": "Tint of the lighter parts of the layer",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "Intensity",
+                                        "description": "Intensity of the effect, 0 means the layer is unchanged. 100 means full effect",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "custom-effect"  : {
+                "type": "object",
+                "title": "Custom Effect",
+                "description": "Some lottie files use ty = 5 for many different effects",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 5
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "spherize-effect"  : {
+                "type": "object",
+                "title": "Spherize Effect",
+                "description": "",
+                "caniuse": "effect-cc-sphere",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 33
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "radius",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "center",
+                                        "$ref": "#/$defs/effect-values/point"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "twirl-effect"  : {
+                "type": "object",
+                "title": "Twirl Effect",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 30
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Angle",
+                                        "$ref": "#/$defs/effect-values/angle"
+                                    },
+                                    {
+                                        "title": "Radius",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Center",
+                                        "$ref": "#/$defs/effect-values/point"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ef"
+                        ]
+                    }
+                ]
+            },
+            "tritone-effect"  : {
+                "type": "object",
+                "title": "Tritone Effect",
+                "description": "Maps layers colors based on bright/mid/dark colors",
+                "caniuse": "effect-tritone",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 23
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "bright",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "mid",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "dark",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "displacement-map-effect"  : {
+                "type": "object",
+                "title": "Displacement Map Effect",
+                "description": "",
+                "caniuse": "effect-displacement-map",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 27
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Displacement Map Layer",
+                                        "$ref": "#/$defs/effect-values/layer"
+                                    },
+                                    {
+                                        "title": "Use For Horizontal Displacement",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Max Horizontal Displacement",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Use For Vertical Displacement",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Max Vertical Displacement",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Displacement Map Behavior",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Edge Behavior",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Expand Output",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ef"
+                        ]
+                    }
+                ]
+            },
+            "radial-wipe-effect"  : {
+                "type": "object",
+                "title": "Radial Wipe",
+                "caniuse": "effect-radial-wipe",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 26
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Completion",
+                                        "description": "Between 0 and 100",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Start Angle",
+                                        "$ref": "#/$defs/effect-values/angle"
+                                    },
+                                    {
+                                        "title": "Wipe Center",
+                                        "$ref": "#/$defs/effect-values/point"
+                                    },
+                                    {
+                                        "title": "Wipe",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Feather",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "matte3-effect"  : {
+                "type": "object",
+                "title": "Set Matte Effect",
+                "description": "Uses a layer as a mask",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 28
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Layer",
+                                        "description": "Use this layer as a mask",
+                                        "$ref": "#/$defs/effect-values/layer"
+                                    },
+                                    {
+                                        "title": "Channel",
+                                        "description": "Channel to use as a mask:\n1 - Red\n2 - Green\n3 - Blue\n4 - Alpha\n5 - Luminance\n6 - Hue\n7 - Lightness\n8 - Saturation\n9 - Full\n10 - Off",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Invert",
+                                        "description": "Use 0 as opaque value when true",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Stretch To Fit",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Show Mask",
+                                        "description": "If false, the mask layer won't be shown",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Premultiply Mask",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "puppet-effect"  : {
+                "type": "object",
+                "title": "Puppet Effect",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 34
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Puppet Engine",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Mesh Rotation Refinement",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "On Transparent",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "03",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ef"
+                        ]
+                    }
+                ]
+            },
+            "stroke-effect"  : {
+                "type": "object",
+                "title": "Stroke Effect",
+                "description": "",
+                "caniuse": "effect-stroke",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 22
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "00",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "01",
+                                        "$ref": "#/$defs/effect-values/checkbox"
+                                    },
+                                    {
+                                        "title": "02",
+                                        "$ref": "#/$defs/effect-values/checkbox"
+                                    },
+                                    {
+                                        "title": "color",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "04",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "05",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "06",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "07",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "08",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "09",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "type",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "pro-levels-effect"  : {
+                "type": "object",
+                "title": "Pro Levels Effect",
+                "description": "",
+                "caniuse": "effect-color-levels-individual-controls",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 24
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "00",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "01",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    },
+                                    {
+                                        "title": "02",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    },
+                                    {
+                                        "title": "comp_inblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "comp_inwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "comp_gamma",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "comp_outblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "comp_outwhite",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    },
+                                    {
+                                        "title": "08",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    },
+                                    {
+                                        "title": "09",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "r_inblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "r_inwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "r_gamma",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "r_outblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "r_outwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "15",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "16",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "g_inblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "g_inwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "g_gamma",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "g_outblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "g_outwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "22",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "23",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "b_inblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "b_inwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "b_gamma",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "b_outblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "b_outwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "29",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "a_inblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "a_inwhite",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "a_gamma",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "a_outblack",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "a_outwhite",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "effect"  : {
+                "type": "object",
+                "title": "Effect",
+                "description": "Layer effect",
+                "caniuse": "effects",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ef": {
+                                "title": "Effect Values",
+                                "type": "array",
+                                "items": {
+                                    "oneOf": [
+                                        {
+                                            "$ref": "#/$defs/effect-values/no-value"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/angle"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/checkbox"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/color"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/drop-down"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/ignored"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/layer"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/point"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effect-values/slider"
+                                        }
+                                    ]
+                                }
+                            },
+                            "np": {
+                                "title": "Property Count",
+                                "description": "Number of values in ef",
+                                "type": "integer"
+                            },
+                            "ix": {
+                                "title": "Effect Index",
+                                "type": "integer"
+                            },
+                            "ty": {
+                                "title": "Type",
+                                "description": "Effect type",
+                                "type": "integer"
+                            },
+                            "en": {
+                                "title": "Enabled",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 1
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ef"
+                        ]
+                    }
+                ]
+            },
+            "wavy-effect"  : {
+                "type": "object",
+                "title": "Wavy Effect",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 32
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Radius",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Center",
+                                        "$ref": "#/$defs/effect-values/point"
+                                    },
+                                    {
+                                        "title": "Conversion type",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Speed",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "Width",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Height",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Phase",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ef"
+                        ]
+                    }
+                ]
+            },
+            "mesh-warp-effect"  : {
+                "type": "object",
+                "title": "Mesh Warp Effect",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 31
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "Rows",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Columns",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "Quality",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "03",
+                                        "$ref": "#/$defs/effect-values/no-value"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ef"
+                        ]
+                    }
+                ]
+            },
+            "fill-effect"  : {
+                "type": "object",
+                "title": "Fill Effect",
+                "description": "Replaces the whole layer with the given color",
+                "caniuse": "effect-fill",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/effects/effect"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "type": "integer",
+                                "const": 21
+                            },
+                            "ef": {
+                                "title": "Effect values",
+                                "type": "array",
+                                "prefixItems": [
+                                    {
+                                        "title": "00",
+                                        "$ref": "#/$defs/effect-values/point"
+                                    },
+                                    {
+                                        "title": "01",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "color",
+                                        "$ref": "#/$defs/effect-values/color"
+                                    },
+                                    {
+                                        "title": "03",
+                                        "$ref": "#/$defs/effect-values/drop-down"
+                                    },
+                                    {
+                                        "title": "04",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "05",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    },
+                                    {
+                                        "title": "opacity",
+                                        "description": "Opacity in [0, 1]",
+                                        "$ref": "#/$defs/effect-values/slider"
+                                    }
+                                ]
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            }
+        },
+        "helpers": {
+            "mask"  : {
+                "type": "object",
+                "title": "Mask",
+                "caniuse": "mask",
+                "description": "Bezier shape used to mask/clip a layer",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "inv": {
+                                "title": "Inverted",
+                                "caniuse": "mask-inverted",
+                                "type": "boolean",
+                                "default": false
+                            },
+                            "pt": {
+                                "title": "Shape",
+                                "$ref": "#/$defs/animated-properties/shape-property"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "caniuse": "mask-opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "mode": {
+                                "title": "Mode",
+                                "caniuse": "mask-modes",
+                                "$ref": "#/$defs/constants/mask-mode",
+                                "default": "i"
+                            },
+                            "x": {
+                                "title": "Expand",
+                                "caniuse": "mask-expansion",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "transform"  : {
+                "type": "object",
+                "title": "Transform",
+                "description": "Layer transform",
+                "allOf": [
+                    {
+                        "properties": {
+                            "a": {
+                                "title": "Anchor Point",
+                                "caniuse": "transform-anchor-point",
+                                "description": "Anchor point: a position (relative to its parent) around which transformations are applied (ie: center for rotation / scale)",
+                                "$ref": "#/$defs/animated-properties/position"
+                            },
+                            "s": {
+                                "title": "Scale",
+                                "caniuse": "transform-scale",
+                                "description": "Scale factor, [100, 100] for no scaling",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "caniuse": "transform-opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sk": {
+                                "title": "Skew",
+                                "caniuse": "transform-skew",
+                                "description": "Skew amount as an angle in degrees",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sa": {
+                                "title": "Skew Axis",
+                                "caniuse": "transform-skew",
+                                "description": "Direction along which skew is applied, in degrees (0 skews along the X axis, 90 along the Y axis)",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        }
+                    },
+                    {
+                        "anyOf": [
+                            {
+                                "oneOf": [
+                                    {
+                                        "properties": {
+                                            "p": {
+                                                "title": "Position",
+                                                "caniuse": "transform-position",
+                                                "description": "Position / Translation",
+                                                "$ref": "#/$defs/animated-properties/position"
+                                            }
+                                        }
+                                    },
+                                    {
+                                        "properties": {
+                                            "p": {
+                                                "title": "Position",
+                                                "description": "Position / Translation with split components",
+                                                "$ref": "#/$defs/animated-properties/split-vector"
+                                            }
+                                        }
+                                    }
+                                ]
+                            },
+                            {
+                                "oneOf": [
+                                    {
+                                        "properties": {
+                                            "r": {
+                                                "title": "Rotation",
+                                                "caniuse": "transform-rotation",
+                                                "description": "Rotation in degrees, clockwise",
+                                                "$ref": "#/$defs/animated-properties/value"
+                                            }
+                                        }
+                                    },
+                                    {
+                                        "properties": {
+                                            "rx": {
+                                                "title": "X Rotation",
+                                                "description": "Split rotation component",
+                                                "$ref": "#/$defs/animated-properties/value"
+                                            },
+                                            "ry": {
+                                                "title": "Y Rotation",
+                                                "description": "Split rotation component",
+                                                "$ref": "#/$defs/animated-properties/value"
+                                            },
+                                            "rz": {
+                                                "title": "Z Rotation",
+                                                "description": "Split rotation component, equivalent to r when not split",
+                                                "$ref": "#/$defs/animated-properties/value"
+                                            },
+                                            "or": {
+                                                "title": "Orientation",
+                                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                                            }
+                                        }
+                                    }
+                                ]
+                            }
+                        ]
+                    }
+                ]
+            },
+            "bezier"  : {
+                "type": "object",
+                "title": "Bezier",
+                "description": "Single bezier curve",
+                "properties": {
+                    "c": {
+                        "title": "Closed",
+                        "type": "boolean",
+                        "default": false
+                    },
+                    "i": {
+                        "title": "In Tangents",
+                        "type": "array",
+                        "description": "Array of points, each point is an array of coordinates.\nThese points are along the in tangents relative to the corresponding v.",
+                        "items": {
+                            "type": "array",
+                            "items": {
+                                "type": "number",
+                                "default": []
+                            }
+                        }
+                    },
+                    "o": {
+                        "title": "Out Tangents",
+                        "type": "array",
+                        "description": "Array of points, each point is an array of coordinates.\nThese points are along the out tangents relative to the corresponding v.",
+                        "items": {
+                            "type": "array",
+                            "items": {
+                                "type": "number",
+                                "default": []
+                            }
+                        }
+                    },
+                    "v": {
+                        "title": "Vertices",
+                        "description": "Array of points, each point is an array of coordinates.\nThese points are along the bezier path",
+                        "type": "array",
+                        "items": {
+                            "type": "array",
+                            "items": {
+                                "type": "number",
+                                "default": []
+                            }
+                        }
+                    }
+                },
+                "required": [
+                    "i",
+                    "v",
+                    "o"
+                ]
+            },
+            "visual-object": {
+                "type": "object",
+                "title": "Visual Object",
+                "description": "",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "nm": {
+                                "title": "Name",
+                                "description": "Name, as seen from editors and the like",
+                                "type": "string"
+                            },
+                            "mn": {
+                                "title": "Match Name",
+                                "description": "Match name, used in expressions",
+                                "type": "string"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "color"  : {
+                "type": "array",
+                "title": "Color",
+                "description": "Color as a [r, g, b] array with values in [0, 1]",
+                "items": {
+                    "type": "number",
+                    "minimum": 0,
+                    "maximum": 1
+                },
+                "minItems": 3,
+                "maxItems": 4
+            },
+            "marker"  : {
+                "type": "object",
+                "title": "Marker",
+                "description": "Defines named portions of the composition.",
+                "properties": {
+                    "cm": {
+                        "title": "Comment",
+                        "type": "string"
+                    },
+                    "tm": {
+                        "title": "Time",
+                        "type": "number"
+                    },
+                    "dr": {
+                        "title": "Duration",
+                        "type": "number"
+                    }
+                }
+            },
+            "int-boolean"  : {
+                "type": "integer",
+                "title": "Integer Boolean",
+                "description": "Represents boolean values as an integer. 0 is false, 1 is true.",
+                "default": 0,
+                "examples": [
+                    0
+                ],
+                "enum": [
+                    0,
+                    1
+                ],
+                "oneOf": [
+                    {
+                        "title": "True",
+                        "const": 1
+                    },
+                    {
+                        "title": "False",
+                        "const": 0
+                    }
+                ]
+            }
+        },
+        "layers": {
+            "null-layer"  : {
+                "type": "object",
+                "title": "Null Layer",
+                "description": "Layer with no data, useful to group layers together",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/visual-layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 3
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "audio-settings"  : {
+                "type": "object",
+                "title": "Audio Settings",
+                "description": "",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "lv": {
+                                "title": "Level",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            }
+                        },
+                        "required": [
+                            "lv"
+                        ]
+                    }
+                ]
+            },
+            "audio-layer"  : {
+                "type": "object",
+                "title": "Audio Layer",
+                "description": "A layer playing sounds",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 6
+                            },
+                            "au": {
+                                "title": "Audio Settings",
+                                "$ref": "#/$defs/layers/audio-settings"
+                            },
+                            "refId": {
+                                "title": "Sound Id",
+                                "description": "ID of the sound as specified in the assets",
+                                "type": "string"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "au"
+                        ]
+                    }
+                ]
+            },
+            "image-layer"  : {
+                "type": "object",
+                "title": "Image Layer",
+                "description": "Layer that shows an image asset",
+                "caniuse": "layer-image",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/visual-layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 2
+                            },
+                            "refId": {
+                                "title": "Image Id",
+                                "description": "ID of the image as specified in the assets",
+                                "type": "string",
+                                "default": ""
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "refId"
+                        ]
+                    }
+                ]
+            },
+            "camera-layer"  : {
+                "type": "object",
+                "title": "Camera Layer",
+                "description": "3D Camera",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 13
+                            },
+                            "ks": {
+                                "title": "Transform",
+                                "description": "Layer transform",
+                                "$ref": "#/$defs/helpers/transform"
+                            },
+                            "pe": {
+                                "title": "Perspective",
+                                "description": "Distance from the Z=0 plane.\nSmall values yield a higher perspective effect.",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ks",
+                            "pe"
+                        ]
+                    }
+                ]
+            },
+            "visual-layer"  : {
+                "type": "object",
+                "title": "Visual Layer",
+                "description": "Layer used to affect visual elements",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ks": {
+                                "title": "Transform",
+                                "caniuse": "transform",
+                                "description": "Layer transform",
+                                "$ref": "#/$defs/helpers/transform"
+                            },
+                            "ao": {
+                                "title": "Auto Orient",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0,
+                                "description": "If 1, The layer will rotate itself to match its animated position path"
+                            },
+                            "tt": {
+                                "title": "Matte Mode",
+                                "caniuse": "property-matte-mask",
+                                "$ref": "#/$defs/constants/matte-mode",
+                                "description": "Defines the track matte mode for the layer"
+                            },
+                            "tp": {
+                                "title": "Matte Parent",
+                                "type": "integer",
+                                "description": "Index of the layer used as matte, if omitted assume the layer above the current one"
+                            },
+                            "td": {
+                                "title": "Matte Target",
+                                "caniuse": "property-matte-mask",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "description": "If set to 1, it means a layer is using this layer as a track matte"
+                            },
+                            "hasMask": {
+                                "title": "Has Masks",
+                                "caniuse": "mask",
+                                "description": "Whether the layer has masks applied",
+                                "type": "boolean"
+                            },
+                            "masksProperties": {
+                                "title": "Masks",
+                                "caniuse": "mask",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/helpers/mask"
+                                }
+                            },
+                            "ef": {
+                                "title": "Effects",
+                                "description": "List of layer effects",
+                                "caniuse": "effects",
+                                "type": "array",
+                                "items": {
+                                    "oneOf": [
+                                        {
+                                            "$ref": "#/$defs/effects/custom-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/drop-shadow-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/fill-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/gaussian-blur-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/matte3-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/pro-levels-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/stroke-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/tint-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/tritone-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/radial-wipe-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/wavy-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/puppet-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/spherize-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/mesh-warp-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/displacement-map-effect"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/effects/twirl-effect"
+                                        }
+                                    ]
+                                }
+                            },
+                            "mb": {
+                                "title": "Motion Blur",
+                                "description": "Whether motion blur is enabled for the layer",
+                                "type": "boolean"
+                            },
+                            "sy": {
+                                "title": "Layer style",
+                                "caniuse": "styles",
+                                "description": "Styling effects for this layer",
+                                "type": "array",
+                                "items": {
+                                    "oneOf": [
+                                        {
+                                            "$ref": "#/$defs/styles/stroke-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/drop-shadow-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/inner-shadow-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/outer-glow-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/inner-glow-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/bevel-emboss-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/satin-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/color-overlay-style"
+                                        },
+                                        {
+                                            "$ref": "#/$defs/styles/gradient-overlay-style"
+                                        }
+                                    ]
+                                }
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/constants/blend-mode",
+                                "default": 0
+                            },
+                            "cl": {
+                                "title": "CSS Class",
+                                "description": "CSS class used by the SVG renderer",
+                                "type": "string"
+                            },
+                            "ln": {
+                                "title": "Layer XML ID",
+                                "description": "id attribute used by the SVG renderer",
+                                "type": "string"
+                            },
+                            "tg": {
+                                "title": "Layer XML tag name",
+                                "description": "tag name used by the SVG renderer",
+                                "type": "string"
+                            },
+                            "cp": {
+                                "deprecated": true,
+                                "title": "Collapse Transform",
+                                "description": "This is deprecated in favour of ct",
+                                "type": "boolean"
+                            },
+                            "ct": {
+                                "title": "Collapse Transform",
+                                "description": "Marks that transforms should be applied before masks",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            }
+                        },
+                        "required": [
+                            "ks"
+                        ]
+                    }
+                ]
+            },
+            "solid-color-layer"  : {
+                "type": "object",
+                "title": "Solid Color Layer",
+                "description": "Layer with a solid color rectangle",
+                "caniuse": "layer-solid",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/visual-layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 1
+                            },
+                            "sc": {
+                                "title": "Color",
+                                "description": "Color of the layer, unlike most other places, the color is a #rrggbb hex string",
+                                "type": "string",
+                                "default": ""
+                            },
+                            "sh": {
+                                "title": "Height",
+                                "type": "number"
+                            },
+                            "sw": {
+                                "title": "Width",
+                                "type": "number"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "sc",
+                            "sw",
+                            "sh"
+                        ]
+                    }
+                ]
+            },
+            "text-layer"  : {
+                "type": "object",
+                "title": "Text Layer",
+                "description": "Layer with some text",
+                "caniuse": "layer-text",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/visual-layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 5
+                            },
+                            "t": {
+                                "title": "Data",
+                                "$ref": "#/$defs/text/text-data"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "t"
+                        ]
+                    }
+                ]
+            },
+            "data-layer"  : {
+                "type": "object",
+                "title": "Data Layer",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 15
+                            },
+                            "refId": {
+                                "title": "Data source Id",
+                                "description": "ID of the data source in assets",
+                                "type": "string"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "precomposition-layer"  : {
+                "type": "object",
+                "title": "Precomposition Layer",
+                "description": "Layer that renders a Precomposition asset",
+                "caniuse": "layer-precomp",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/visual-layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 0
+                            },
+                            "refId": {
+                                "title": "Reference Id",
+                                "description": "ID of the precomp as specified in the assets",
+                                "type": "string"
+                            },
+                            "w": {
+                                "title": "Width",
+                                "description": "Width of the clipping rect",
+                                "type": "integer"
+                            },
+                            "h": {
+                                "title": "Height",
+                                "description": "Height of the clipping rect",
+                                "type": "integer"
+                            },
+                            "tm": {
+                                "title": "Time Remapping",
+                                "caniuse": "property-timeremap",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "refId",
+                            "w",
+                            "h"
+                        ]
+                    }
+                ]
+            },
+            "shape-layer"  : {
+                "type": "object",
+                "title": "Shape Layer",
+                "description": "Layer containing Shapes",
+                "caniuse": "layer-shape",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/layers/visual-layer"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer type",
+                                "type": "integer",
+                                "const": 4
+                            },
+                            "shapes": {
+                                "title": "Shapes",
+                                "$ref": "#/$defs/shapes/shape-list"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "shapes"
+                        ]
+                    }
+                ]
+            },
+            "layer"  : {
+                "type": "object",
+                "title": "Layer",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ddd": {
+                                "title": "Threedimensional",
+                                "description": "Whether the layer is threedimensional",
+                                "$ref": "#/$defs/helpers/int-boolean",
+                                "default": 0
+                            },
+                            "hd": {
+                                "title": "Hidden",
+                                "description": "Whether the layer is hidden",
+                                "type": "boolean"
+                            },
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "oneOf": [
+                                    {
+                                        "const": 0,
+                                        "title": "Precomposition layer"
+                                    },
+                                    {
+                                        "const": 1,
+                                        "title": "Solid color layer"
+                                    },
+                                    {
+                                        "const": 2,
+                                        "title": "Image layer"
+                                    },
+                                    {
+                                        "const": 3,
+                                        "title": "Null layer"
+                                    },
+                                    {
+                                        "const": 4,
+                                        "title": "Shape layer"
+                                    },
+                                    {
+                                        "const": 5,
+                                        "title": "Text layer"
+                                    },
+                                    {
+                                        "const": 6,
+                                        "title": "Audio layer"
+                                    },
+                                    {
+                                        "const": 7,
+                                        "title": "Video placeholder"
+                                    },
+                                    {
+                                        "const": 8,
+                                        "title": "Image sequence"
+                                    },
+                                    {
+                                        "const": 9,
+                                        "title": "Video layer"
+                                    },
+                                    {
+                                        "const": 10,
+                                        "title": "Image placeholder"
+                                    },
+                                    {
+                                        "const": 11,
+                                        "title": "Guide layer"
+                                    },
+                                    {
+                                        "const": 12,
+                                        "title": "Adjustment layer"
+                                    },
+                                    {
+                                        "const": 13,
+                                        "title": "Camera"
+                                    },
+                                    {
+                                        "const": 14,
+                                        "title": "Light layer"
+                                    },
+                                    {
+                                        "const": 15,
+                                        "title": "Data layer"
+                                    }
+                                ]
+                            },
+                            "ind": {
+                                "title": "Index",
+                                "type": "integer",
+                                "description": "Index that can be used for parenting and referenced in expressions"
+                            },
+                            "parent": {
+                                "title": "Parent Index",
+                                "description": "Must be the ind property of another layer",
+                                "type": "integer"
+                            },
+                            "sr": {
+                                "title": "Time Stretch",
+                                "caniuse": "property-time-stretch",
+                                "type": "number",
+                                "default": 1
+                            },
+                            "ip": {
+                                "title": "In Point",
+                                "description": "Frame when the layer becomes visible",
+                                "type": "number"
+                            },
+                            "op": {
+                                "title": "Out Point",
+                                "description": "Frame when the layer becomes invisible",
+                                "type": "number"
+                            },
+                            "st": {
+                                "title": "Start Time",
+                                "type": "number",
+                                "default": 0
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "st",
+                            "ip",
+                            "op"
+                        ]
+                    }
+                ]
+            }
+        },
+        "shapes": {
+            "shape-list"  : {
+                "title": "Shape List",
+                "description": "List of valid shapes",
+                "type": "array",
+                "items": {
+                    "oneOf": [
+                        {
+                            "$ref": "#/$defs/shapes/ellipse"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/fill"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/gradient-fill"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/gradient-stroke"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/group"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/path"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/polystar"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/pucker-bloat"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/rectangle"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/repeater"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/rounded-corners"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/stroke"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/transform"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/trim"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/twist"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/merge"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/offset-path"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/zig-zag"
+                        },
+                        {
+                            "$ref": "#/$defs/shapes/no-style"
+                        }
+                    ]
+                }
+            },
+            "rectangle"  : {
+                "type": "object",
+                "title": "Rectangle",
+                "description": "A simple rectangle shape",
+                "caniuse": "shape-rectangle",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "rc"
+                            },
+                            "p": {
+                                "title": "Position",
+                                "description": "Center of the rectangle",
+                                "$ref": "#/$defs/animated-properties/position"
+                            },
+                            "s": {
+                                "title": "Size",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            },
+                            "r": {
+                                "title": "Rounded",
+                                "description": "Rounded corners radius",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "s",
+                            "p",
+                            "r"
+                        ]
+                    }
+                ]
+            },
+            "twist"  : {
+                "type": "object",
+                "title": "Twist",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "tw"
+                            },
+                            "a": {
+                                "title": "Angle",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "c": {
+                                "title": "Center",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "rounded-corners"  : {
+                "type": "object",
+                "title": "Rounded Corners",
+                "description": "Rounds corners of other shapes",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/modifier"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "rd"
+                            },
+                            "r": {
+                                "title": "Radius",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "r"
+                        ]
+                    }
+                ]
+            },
+            "polystar"  : {
+                "type": "object",
+                "title": "PolyStar",
+                "description": "Star or regular polygon",
+                "caniuse": "shape-polystar",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "sr"
+                            },
+                            "p": {
+                                "title": "Position",
+                                "$ref": "#/$defs/animated-properties/position"
+                            },
+                            "or": {
+                                "title": "Outer Radius",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "os": {
+                                "title": "Outer Roundness",
+                                "description": "Outer Roundness as a percentage",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "r": {
+                                "title": "Rotation",
+                                "description": "Rotation, clockwise in degrees",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "pt": {
+                                "title": "Points",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sy": {
+                                "title": "Star Type",
+                                "description": "Star type, 1 for Star, 2 for Polygon",
+                                "$ref": "#/$defs/constants/star-type",
+                                "default": 1
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "or",
+                            "os",
+                            "pt",
+                            "p",
+                            "r"
+                        ]
+                    },
+                    {
+                        "if": {
+                            "properties": {
+                                "sy": {
+                                    "const": 1
+                                }
+                            }
+                        },
+                        "then": {
+                            "properties": {
+                                "ir": {
+                                    "title": "Inner Radius",
+                                    "$ref": "#/$defs/animated-properties/value"
+                                },
+                                "is": {
+                                    "title": "Inner Roundness",
+                                    "description": "Inner Roundness as a percentage",
+                                    "$ref": "#/$defs/animated-properties/value"
+                                }
+                            },
+                            "required": [
+                                "ir",
+                                "is"
+                            ]
+                        }
+                    }
+                ]
+            },
+            "shape-element"  : {
+                "type": "object",
+                "title": "Shape Element",
+                "description": "Base class for all elements of ShapeLayer and Group",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "hd": {
+                                "title": "Hidden",
+                                "description": "Whether the shape is hidden",
+                                "type": "boolean"
+                            },
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "oneOf": [
+                                    {
+                                        "const": "rc",
+                                        "title": "Rectangle"
+                                    },
+                                    {
+                                        "const": "el",
+                                        "title": "Ellipse"
+                                    },
+                                    {
+                                        "const": "sr",
+                                        "title": "Polygon / Star"
+                                    },
+                                    {
+                                        "const": "sh",
+                                        "title": "Path"
+                                    },
+                                    {
+                                        "const": "fl",
+                                        "title": "Fill"
+                                    },
+                                    {
+                                        "const": "st",
+                                        "title": "Stroke"
+                                    },
+                                    {
+                                        "const": "gf",
+                                        "title": "Gradient fill"
+                                    },
+                                    {
+                                        "const": "gs",
+                                        "title": "Gradient stroke"
+                                    },
+                                    {
+                                        "const": "no",
+                                        "title": "No Style"
+                                    },
+                                    {
+                                        "const": "gr",
+                                        "title": "Group"
+                                    },
+                                    {
+                                        "const": "tr",
+                                        "title": "Transform"
+                                    },
+                                    {
+                                        "const": "rd",
+                                        "title": "Rounded corners"
+                                    },
+                                    {
+                                        "const": "pb",
+                                        "title": "Pucker / bloat"
+                                    },
+                                    {
+                                        "const": "mm",
+                                        "title": "Merge"
+                                    },
+                                    {
+                                        "const": "tw",
+                                        "title": "Twist"
+                                    },
+                                    {
+                                        "const": "op",
+                                        "title": "Offset path"
+                                    },
+                                    {
+                                        "const": "zz",
+                                        "title": "Zig zag"
+                                    },
+                                    {
+                                        "const": "rp",
+                                        "title": "Repeater"
+                                    },
+                                    {
+                                        "const": "tm",
+                                        "title": "Trim"
+                                    }
+                                ]
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/constants/blend-mode"
+                            },
+                            "ix": {
+                                "title": "Property index",
+                                "description": "Index used in expressions",
+                                "type": "integer"
+                            },
+                            "cl": {
+                                "title": "CSS Class",
+                                "description": "CSS class used by the SVG renderer",
+                                "type": "string"
+                            },
+                            "ln": {
+                                "title": "Layer XML ID",
+                                "description": "id attribute used by the SVG renderer",
+                                "type": "string"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "ellipse"  : {
+                "type": "object",
+                "title": "Ellipse",
+                "description": "Ellipse shape",
+                "caniuse": "shape-ellipse",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "el"
+                            },
+                            "p": {
+                                "title": "Position",
+                                "$ref": "#/$defs/animated-properties/position"
+                            },
+                            "s": {
+                                "title": "Size",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "s",
+                            "p"
+                        ]
+                    }
+                ]
+            },
+            "modifier"  : {
+                "type": "object",
+                "title": "Modifier",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    }
+                ]
+            },
+            "trim"  : {
+                "type": "object",
+                "title": "Trim",
+                "description": "Trims shapes into a segment",
+                "caniuse": "shape-trim-path",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/modifier"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "tm"
+                            },
+                            "s": {
+                                "title": "Start",
+                                "description": "Segment start",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "e": {
+                                "title": "End",
+                                "description": "Segment end",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "o": {
+                                "title": "Offset",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "m": {
+                                "title": "Multiple",
+                                "description": "How to treat multiple copies",
+                                "$ref": "#/$defs/constants/trim-multiple-shapes"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "o",
+                            "s",
+                            "e"
+                        ]
+                    }
+                ]
+            },
+            "transform"  : {
+                "type": "object",
+                "title": "Transform Shape",
+                "description": "Group transform",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "$ref": "#/$defs/helpers/transform"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "tr"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "offset-path"  : {
+                "type": "object",
+                "title": "Offset Path",
+                "caniuse": "shape-offset-path",
+                "description": "Interpolates the shape with its center point and bezier tangents with the opposite direction",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "op"
+                            },
+                            "a": {
+                                "title": "Amount",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "lj": {
+                                "title": "Line Join",
+                                "$ref": "#/$defs/constants/line-join",
+                                "default": 2
+                            },
+                            "ml": {
+                                "title": "Miter Limit",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "no-style"  : {
+                "type": "object",
+                "title": "No Style",
+                "description": "Represents a style for shapes without fill or stroke",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "no"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "gradient"  : {
+                "type": "object",
+                "title": "Gradient",
+                "description": "",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "s": {
+                                "title": "Start Point",
+                                "description": "Starting point for the gradient",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            },
+                            "e": {
+                                "title": "End Point",
+                                "description": "End point for the gradient",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            },
+                            "t": {
+                                "title": "Gradient Type",
+                                "description": "Type of the gradient",
+                                "$ref": "#/$defs/constants/gradient-type",
+                                "default": 1
+                            },
+                            "h": {
+                                "title": "Highlight Length",
+                                "description": "Highlight Length, as a percentage between s and e",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Highlight Angle",
+                                "description": "Highlight Angle, relative to the direction from s to e",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "g": {
+                                "title": "Colors",
+                                "description": "Gradient colors",
+                                "$ref": "#/$defs/animated-properties/gradient-colors"
+                            }
+                        },
+                        "required": [
+                            "s",
+                            "e",
+                            "g"
+                        ]
+                    }
+                ]
+            },
+            "base-stroke"  : {
+                "type": "object",
+                "title": "Base Stroke",
+                "description": "",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "lc": {
+                                "title": "Line Cap",
+                                "$ref": "#/$defs/constants/line-cap",
+                                "default": 2
+                            },
+                            "lj": {
+                                "title": "Line Join",
+                                "$ref": "#/$defs/constants/line-join",
+                                "default": 2
+                            },
+                            "ml": {
+                                "title": "Miter Limit",
+                                "type": "number",
+                                "default": 0
+                            },
+                            "ml2": {
+                                "title": "Miter Limit",
+                                "description": "Animatable alternative to ml",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "description": "Opacity, 100 means fully opaque",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "w": {
+                                "title": "Width",
+                                "description": "Stroke width",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "d": {
+                                "title": "Dashes",
+                                "description": "Dashed line definition",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/shapes/stroke-dash"
+                                }
+                            }
+                        },
+                        "required": [
+                            "o",
+                            "w"
+                        ]
+                    }
+                ]
+            },
+            "group"  : {
+                "type": "object",
+                "title": "Group",
+                "description": "Shape Element that can contain other shapes",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "gr"
+                            },
+                            "np": {
+                                "title": "Number Of Properties",
+                                "type": "number"
+                            },
+                            "it": {
+                                "title": "Shapes",
+                                "$ref": "#/$defs/shapes/shape-list"
+                            },
+                            "cix": {
+                                "title": "Property index",
+                                "description": "Index used in expressions",
+                                "type": "integer"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "gradient-fill"  : {
+                "type": "object",
+                "title": "Gradient Fill",
+                "description": "Gradient fill",
+                "caniuse": "shape-fill-gradient",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "$ref": "#/$defs/shapes/gradient"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "gf"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "r": {
+                                "title": "Fill Rule",
+                                "$ref": "#/$defs/constants/fill-rule"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "o"
+                        ]
+                    }
+                ]
+            },
+            "fill"  : {
+                "type": "object",
+                "title": "Fill",
+                "description": "Solid fill color",
+                "caniuse": "shape-fill",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "fl"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "description": "Opacity, 100 means fully opaque",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "r": {
+                                "title": "Fill Rule",
+                                "$ref": "#/$defs/constants/fill-rule"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "c",
+                            "o"
+                        ]
+                    }
+                ]
+            },
+            "shape"  : {
+                "type": "object",
+                "title": "Shape",
+                "description": "Drawable shape",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "d": {
+                                "title": "Direction",
+                                "description": "Direction the shape is drawn as, mostly relevant when using trim path",
+                                "$ref": "#/$defs/constants/shape-direction"
+                            }
+                        }
+                    }
+                ]
+            },
+            "repeater"  : {
+                "type": "object",
+                "title": "Repeater",
+                "description": "Duplicates previous shapes in a group",
+                "caniuse": "shape-repeater",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/modifier"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "rp"
+                            },
+                            "c": {
+                                "title": "Copies",
+                                "description": "Number of copies",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "o": {
+                                "title": "Offset",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "m": {
+                                "title": "Composite",
+                                "description": "Stacking order",
+                                "$ref": "#/$defs/constants/composite",
+                                "default": 1
+                            },
+                            "tr": {
+                                "title": "Transform",
+                                "description": "Transform applied to each copy",
+                                "$ref": "#/$defs/shapes/repeater-transform"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "c",
+                            "tr"
+                        ]
+                    }
+                ]
+            },
+            "path"  : {
+                "type": "object",
+                "title": "Path",
+                "description": "Animatable Bezier curve",
+                "caniuse": "shape-path",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "sh"
+                            },
+                            "ks": {
+                                "title": "Shape",
+                                "description": "Bezier path",
+                                "$ref": "#/$defs/animated-properties/shape-property"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "ks"
+                        ]
+                    }
+                ]
+            },
+            "stroke"  : {
+                "type": "object",
+                "title": "Stroke",
+                "description": "Solid stroke",
+                "caniuse": "shape-stroke",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "$ref": "#/$defs/shapes/base-stroke"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "st"
+                            },
+                            "c": {
+                                "title": "Color",
+                                "description": "Stroke color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            }
+                        },
+                        "required": [
+                            "ty",
+                            "c"
+                        ]
+                    }
+                ]
+            },
+            "gradient-stroke"  : {
+                "type": "object",
+                "title": "Gradient Stroke",
+                "description": "Gradient stroke",
+                "caniuse": "shape-stroke-gradient",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "$ref": "#/$defs/shapes/base-stroke"
+                    },
+                    {
+                        "$ref": "#/$defs/shapes/gradient"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "gs"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "pucker-bloat"  : {
+                "type": "object",
+                "title": "Pucker Bloat",
+                "description": "Interpolates the shape with its center point and bezier tangents with the opposite direction",
+                "caniuse": "shape-pucker-and-bloat",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "pb"
+                            },
+                            "a": {
+                                "title": "Amount",
+                                "description": "Amount as a percentage",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "repeater-transform"  : {
+                "type": "object",
+                "title": "Repeater Transform",
+                "description": "Transform used by a repeater, the transform is applied to each subsequent repeated object.",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/transform"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "so": {
+                                "title": "Start Opacity",
+                                "description": "Opacity of the first repeated object.",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "eo": {
+                                "title": "End Opacity",
+                                "description": "Opacity of the last repeated object.",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "zig-zag"  : {
+                "type": "object",
+                "title": "Zig Zag",
+                "description": "Changes the edges of affected shapes into a series of peaks and valleys of uniform size",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "zz"
+                            },
+                            "r": {
+                                "title": "Frequency",
+                                "description": "Number of ridges per segment",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "s": {
+                                "title": "Amplitude",
+                                "description": "Distance between peaks and troughs",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "pt": {
+                                "title": "Point Type",
+                                "description": "Point type (1 = corner, 2 = smooth)",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "merge"  : {
+                "type": "object",
+                "title": "Merge",
+                "caniuse": "shape-merge-path",
+                "description": "Boolean operator on shapes",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/shapes/shape-element"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Shape Type",
+                                "type": "string",
+                                "const": "mm"
+                            },
+                            "mm": {
+                                "title": "Merge Mode",
+                                "$ref": "#/$defs/constants/merge-mode",
+                                "default": 1
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "stroke-dash"  : {
+                "type": "object",
+                "title": "Stroke Dash",
+                "description": "An item used to described the dashe pattern in a stroked path",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "n": {
+                                "title": "Dash Type",
+                                "$ref": "#/$defs/constants/stroke-dash-type",
+                                "default": "d"
+                            },
+                            "v": {
+                                "title": "Length",
+                                "description": "Length of the dash",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            }
+        },
+        "styles": {
+            "satin-style"  : {
+                "type": "object",
+                "title": "Satin",
+                "caniuse": "style-satin",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 6
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Angle",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "d": {
+                                "title": "Distance",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "s": {
+                                "title": "Size",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "in": {
+                                "title": "Invert",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "gradient-overlay-style"  : {
+                "type": "object",
+                "title": "Gradient Overlay",
+                "caniuse": "style-gradient-overlay",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 8
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "gf": {
+                                "title": "Gradient",
+                                "$ref": "#/$defs/animated-properties/gradient-colors"
+                            },
+                            "gs": {
+                                "title": "Smoothness",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Angle",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "gt": {
+                                "title": "Gradient Type",
+                                "$ref": "#/$defs/constants/gradient-type"
+                            },
+                            "re": {
+                                "title": "Reverse",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "al": {
+                                "title": "Align",
+                                "description": "Align with layer",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "s": {
+                                "title": "Scale",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "of": {
+                                "title": "Offset",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "color-overlay-style"  : {
+                "type": "object",
+                "title": "Color Overlay",
+                "caniuse": "style-color-overlay",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 7
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "so": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "outer-glow-style"  : {
+                "type": "object",
+                "title": "Outer Glow",
+                "caniuse": "style-outer-glow",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 3
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "r": {
+                                "title": "Range",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ch": {
+                                "title": "Choke Spread",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "no": {
+                                "title": "Noise",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "j": {
+                                "title": "Jitter",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "stroke-style"  : {
+                "type": "object",
+                "title": "Layer Stroke",
+                "caniuse": "style-stroke",
+                "description": "Stroke / frame",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 0
+                            },
+                            "s": {
+                                "title": "Size",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "inner-glow-style"  : {
+                "type": "object",
+                "title": "Inner Glow",
+                "caniuse": "style-inner-glow",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 4
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "r": {
+                                "title": "Range",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sr": {
+                                "title": "Source",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ch": {
+                                "title": "Choke Spread",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "no": {
+                                "title": "Noise",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "j": {
+                                "title": "Jitter",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "layer-style"  : {
+                "type": "object",
+                "title": "Layer Style",
+                "description": "Style applied to a layer",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/visual-object"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Style Type",
+                                "type": "integer"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "drop-shadow-style"  : {
+                "type": "object",
+                "title": "Drop Shadow",
+                "caniuse": "style-drop-shadow",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 1
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Angle",
+                                "description": "Local light angle",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "s": {
+                                "title": "Size",
+                                "description": "Blur size",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "d": {
+                                "title": "Distance",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ch": {
+                                "title": "Choke Spread",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "no": {
+                                "title": "Noise",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "lc": {
+                                "title": "Layer Conceal",
+                                "description": "Layer knowck out drop shadow",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "inner-shadow-style"  : {
+                "type": "object",
+                "title": "Inner Shadow",
+                "caniuse": "style-inner-shadow",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 2
+                            },
+                            "c": {
+                                "title": "Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "o": {
+                                "title": "Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Angle",
+                                "description": "Local light angle",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "s": {
+                                "title": "Size",
+                                "description": "Blur size",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "d": {
+                                "title": "Distance",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ch": {
+                                "title": "Choke Spread",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "bm": {
+                                "title": "Blend Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "no": {
+                                "title": "Noise",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            },
+            "bevel-emboss-style"  : {
+                "type": "object",
+                "title": "Bevel Emboss",
+                "caniuse": "style-bevel-and-emboss",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/styles/layer-style"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ty": {
+                                "title": "Type",
+                                "description": "Layer Type",
+                                "type": "integer",
+                                "const": 5
+                            },
+                            "bs": {
+                                "title": "Bevel Style",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "bt": {
+                                "title": "Technique",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sr": {
+                                "title": "Strength",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "s": {
+                                "title": "Size",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sf": {
+                                "title": "Soften",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ga": {
+                                "title": "Global Angle",
+                                "description": "Use global light",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Angle",
+                                "description": "Local lighting angle",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ll": {
+                                "title": "Altitude",
+                                "description": "Local lighting altitude",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "hm": {
+                                "title": "Highlight Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "hc": {
+                                "title": "Highlight Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "ho": {
+                                "title": "Highlight Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sm": {
+                                "title": "Shadow Mode",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sc": {
+                                "title": "Shadow Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "so": {
+                                "title": "Shadow Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": [
+                            "ty"
+                        ]
+                    }
+                ]
+            }
+        },
+        "text": {
+            "animated-text-document"  : {
+                "type": "object",
+                "title": "Animated Text Document",
+                "description": "Animated property representing the text contents",
+                "properties": {
+                    "k": {
+                        "title": "Keyframes",
+                        "type": "array",
+                        "items": {
+                            "$ref": "#/$defs/text/text-document-keyframe"
+                        }
+                    },
+                    "x": {
+                        "title": "Expression",
+                        "type": "string"
+                    },
+                    "sid": {
+                        "title": "Slot ID",
+                        "description": "One of the ID in the file's slots",
+                        "type": "string"
+                    }
+                },
+                "required": [
+                    "k"
+                ]
+            },
+            "text-document-keyframe"  : {
+                "type": "object",
+                "title": "Text Document Keyframe",
+                "description": "A keyframe containing a text document",
+                "properties": {
+                    "s": {
+                        "title": "Start",
+                        "$ref": "#/$defs/text/text-document"
+                    },
+                    "t": {
+                        "title": "Time",
+                        "type": "number",
+                        "default": 0
+                    }
+                },
+                "required": [
+                    "s",
+                    "t"
+                ]
+            },
+            "text-follow-path"  : {
+                "type": "object",
+                "title": "Text Follow Path",
+                "caniuse": "text-path",
+                "description": "Uses the path described by a layer mask to put the text on said path.",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "m": {
+                                "title": "Mask",
+                                "type": "integer",
+                                "description": "Index of the mask to use"
+                            },
+                            "f": {
+                                "title": "First Margin",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "l": {
+                                "title": "Last Margin",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "r": {
+                                "title": "Reverse Path",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "a": {
+                                "title": "Force Alignment",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "p": {
+                                "title": "Perpendicular To Path",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "font-list"  : {
+                "type": "object",
+                "title": "Font List",
+                "description": "List of fonts",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "list": {
+                                "title": "List",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/text/font"
+                                }
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "character-precomp"  : {
+                "type": "object",
+                "title": "Character Precomp",
+                "description": "Defines a character as a precomp layer",
+                "properties": {
+                    "refId": {
+                        "title": "Reference Id",
+                        "description": "ID of the precomp as specified in the assets",
+                        "type": "string"
+                    },
+                    "ks": {
+                        "title": "Transform",
+                        "description": "Layer transform",
+                        "$ref": "#/$defs/helpers/transform"
+                    },
+                    "ip": {
+                        "title": "In Point",
+                        "description": "Frame when the layer becomes visible",
+                        "type": "number",
+                        "default": 0
+                    },
+                    "op": {
+                        "title": "Out Point",
+                        "description": "Frame when the layer becomes invisible",
+                        "type": "number",
+                        "default": 99999
+                    },
+                    "sr": {
+                        "title": "Time Stretch",
+                        "type": "number",
+                        "default": 1
+                    },
+                    "st": {
+                        "title": "Start Time",
+                        "type": "number",
+                        "default": 0
+                    }
+                },
+                "required": [
+                    "refId"
+                ]
+            },
+            "character-data"  : {
+                "type": "object",
+                "title": "Character Data",
+                "description": "Defines character shapes",
+                "properties": {
+                    "ch": {
+                        "title": "Character",
+                        "type": "string",
+                        "default": ""
+                    },
+                    "fFamily": {
+                        "title": "Font Family",
+                        "type": "string",
+                        "default": ""
+                    },
+                    "size": {
+                        "title": "Font Size",
+                        "type": "number",
+                        "default": 0
+                    },
+                    "style": {
+                        "title": "Font Style",
+                        "type": "string",
+                        "default": ""
+                    },
+                    "w": {
+                        "title": "Width",
+                        "type": "number",
+                        "default": 0
+                    },
+                    "data": {
+                        "title": "Data",
+                        "oneOf": [
+                            {
+                                "$ref": "#/$defs/text/character-shapes"
+                            },
+                            {
+                                "$ref": "#/$defs/text/character-precomp"
+                            }
+                        ]
+                    }
+                },
+                "required": [
+                    "data",
+                    "ch",
+                    "fFamily",
+                    "size",
+                    "style",
+                    "w"
+                ]
+            },
+            "font"  : {
+                "type": "object",
+                "title": "Font",
+                "description": "Describes how a font with given settings should be loaded",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "ascent": {
+                                "title": "Ascent",
+                                "type": "number",
+                                "description": "Text will be moved down based on this value"
+                            },
+                            "fFamily": {
+                                "title": "Font Family",
+                                "type": "string",
+                                "default": "sans"
+                            },
+                            "fName": {
+                                "title": "Name",
+                                "description": "Name used by text documents to reference this font, usually it's fFamily followed by fStyle",
+                                "type": "string",
+                                "default": "sans-Regular"
+                            },
+                            "fStyle": {
+                                "title": "Font Style",
+                                "examples": [
+                                    "Regular",
+                                    "Bold",
+                                    "Bold Italic"
+                                ],
+                                "type": "string",
+                                "default": "Regular"
+                            },
+                            "fPath": {
+                                "title": "Path",
+                                "type": "string"
+                            },
+                            "fWeight": {
+                                "title": "Weight",
+                                "type": "string"
+                            },
+                            "origin": {
+                                "title": "Origin",
+                                "$ref": "#/$defs/constants/font-path-origin"
+                            },
+                            "fClass": {
+                                "type": "string",
+                                "title": "CSS Class",
+                                "description": "CSS Class applied to text objects using this font"
+                            }
+                        },
+                        "required": [
+                            "fFamily",
+                            "fName",
+                            "fStyle"
+                        ]
+                    }
+                ]
+            },
+            "text-data"  : {
+                "type": "object",
+                "title": "Text Data",
+                "description": "Contains all the text data and animation",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "a": {
+                                "title": "Ranges",
+                                "caniuse": "text-animators",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/$defs/text/text-range"
+                                }
+                            },
+                            "d": {
+                                "title": "Document",
+                                "$ref": "#/$defs/text/animated-text-document"
+                            },
+                            "m": {
+                                "title": "Alignment",
+                                "$ref": "#/$defs/text/text-alignment-options"
+                            },
+                            "p": {
+                                "title": "Follow Path",
+                                "$ref": "#/$defs/text/text-follow-path"
+                            }
+                        },
+                        "required": [
+                            "a",
+                            "d",
+                            "m",
+                            "p"
+                        ]
+                    }
+                ]
+            },
+            "text-range-selector"  : {
+                "type": "object",
+                "title": "Text Range Selector",
+                "caniuse": "animators-range-selectors",
+                "properties": {
+                    "t": {
+                        "title": "Expressible",
+                        "$ref": "#/$defs/helpers/int-boolean"
+                    },
+                    "xe": {
+                        "title": "Max Ease",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "ne": {
+                        "title": "Min Ease",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "a": {
+                        "title": "Max Amount",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "b": {
+                        "title": "Based On",
+                        "$ref": "#/$defs/constants/text-based"
+                    },
+                    "rn": {
+                        "title": "Randomize",
+                        "$ref": "#/$defs/helpers/int-boolean"
+                    },
+                    "sh": {
+                        "title": "Shape",
+                        "$ref": "#/$defs/constants/text-shape"
+                    },
+                    "o": {
+                        "title": "Offset",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "r": {
+                        "title": "Range Units",
+                        "caniuse": "range-selectors-units",
+                        "$ref": "#/$defs/constants/text-range-units"
+                    },
+                    "sm": {
+                        "title": "Selector Smoothness",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "s": {
+                        "title": "Start",
+                        "$ref": "#/$defs/animated-properties/value"
+                    },
+                    "e": {
+                        "title": "End",
+                        "$ref": "#/$defs/animated-properties/value"
+                    }
+                },
+                "required": [
+                    "t",
+                    "a",
+                    "b",
+                    "sh"
+                ]
+            },
+            "text-alignment-options"  : {
+                "type": "object",
+                "title": "Text Alignment Options",
+                "description": "",
+                "allOf": [
+                    {
+                        "type": "object",
+                        "properties": {
+                            "a": {
+                                "title": "Alignment",
+                                "description": "Group alignment",
+                                "caniuse": "animators-grouping-alignment",
+                                "$ref": "#/$defs/animated-properties/multi-dimensional"
+                            },
+                            "g": {
+                                "title": "Grouping",
+                                "description": "Anchor point grouping",
+                                "caniuse": "animators-anchor-point-grouping",
+                                "$ref": "#/$defs/constants/text-grouping"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "text-style"  : {
+                "type": "object",
+                "title": "Text Style",
+                "description": "",
+                "allOf": [
+                    {
+                        "$ref": "#/$defs/helpers/transform"
+                    },
+                    {
+                        "type": "object",
+                        "properties": {
+                            "sw": {
+                                "title": "Stroke Width",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sc": {
+                                "title": "Stroke Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "sh": {
+                                "title": "Stroke Hue",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ss": {
+                                "title": "Stroke Saturation",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "sb": {
+                                "title": "Stroke Brightness",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "so": {
+                                "title": "Stroke Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "fc": {
+                                "title": "Fill Color",
+                                "$ref": "#/$defs/animated-properties/color-value"
+                            },
+                            "fh": {
+                                "title": "Fill Hue",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "fs": {
+                                "title": "Fill Saturation",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "fb": {
+                                "title": "Fill Brightness",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "fo": {
+                                "title": "Fill Opacity",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "t": {
+                                "title": "Letter Spacing",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "bl": {
+                                "title": "Blur",
+                                "caniuse": "text-animators-blur",
+                                "$ref": "#/$defs/animated-properties/value"
+                            },
+                            "ls": {
+                                "title": "Line Spacing",
+                                "$ref": "#/$defs/animated-properties/value"
+                            }
+                        },
+                        "required": []
+                    }
+                ]
+            },
+            "text-range"  : {
+                "type": "object",
+                "title": "Text Range",
+                "description": "Range of text with custom animations and style",
+                "caniuse": "animators-range-selectors",
+                "properties": {
+                    "nm": {
+                        "title": "Name",
+                        "type": "string"
+                    },
+                    "s": {
+                        "title": "Selector",
+                        "$ref": "#/$defs/text/text-range-selector"
+                    },
+                    "a": {
+                        "title": "Style",
+                        "$ref": "#/$defs/text/text-style"
+                    }
+                }
+            },
+            "character-shapes"  : {
+                "type": "object",
+                "title": "Character Shape",
+                "description": "Defines a character as shapes",
+                "properties": {
+                    "shapes": {
+                        "title": "Shapes",
+                        "description": "Shapes forming the character",
+                        "$ref": "#/$defs/shapes/shape-list"
+                    }
+                },
+                "required": [
+                    "shapes"
+                ]
+            },
+            "text-document"  : {
+                "type": "object",
+                "title": "Text Document",
+                "description": "",
+                "properties": {
+                    "f": {
+                        "title": "Font Family",
+                        "type": "string",
+                        "default": ""
+                    },
+                    "fc": {
+                        "title": "Fill Color",
+                        "$ref": "#/$defs/helpers/color",
+                        "default": [
+                            0,
+                            0,
+                            0
+                        ]
+                    },
+                    "sc": {
+                        "title": "Stroke Color",
+                        "$ref": "#/$defs/helpers/color"
+                    },
+                    "sw": {
+                        "title": "Stroke Width",
+                        "type": "number",
+                        "default": 0
+                    },
+                    "of": {
+                        "title": "Stroke Over Fill",
+                        "description": "Render stroke above the fill",
+                        "type": "boolean"
+                    },
+                    "s": {
+                        "title": "Font Size",
+                        "type": "number",
+                        "default": 10
+                    },
+                    "lh": {
+                        "title": "Line Height",
+                        "description": "Distance between lines on multiline or wrapped text",
+                        "type": "number"
+                    },
+                    "sz": {
+                        "title": "Wrap Size",
+                        "description": "Size of the box containing the text",
+                        "type": "array",
+                        "minItems": 2,
+                        "maxItems": 2,
+                        "items": {
+                            "type": "number"
+                        }
+                    },
+                    "ps": {
+                        "title": "Wrap Position",
+                        "description": "Position of the box containing the text",
+                        "type": "array",
+                        "minItems": 2,
+                        "maxItems": 2,
+                        "items": {
+                            "type": "number"
+                        }
+                    },
+                    "t": {
+                        "title": "Text",
+                        "type": "string",
+                        "description": "Text, note that newlines are encoded with \r",
+                        "default": ""
+                    },
+                    "j": {
+                        "title": "Justify",
+                        "$ref": "#/$defs/constants/text-justify",
+                        "default": 0
+                    },
+                    "ca": {
+                        "title": "Text Caps",
+                        "$ref": "#/$defs/constants/text-caps"
+                    },
+                    "tr": {
+                        "title": "Tracking",
+                        "description": "Text Tracking",
+                        "type": "number"
+                    },
+                    "ls": {
+                        "title": "Baseline Shift",
+                        "type": "number"
+                    }
+                },
+                "required": [
+                    "f",
+                    "fc",
+                    "s",
+                    "t"
+                ]
+            }
+        }
+    }
+}
+

+
+ + +
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/schema/layers/audio-layer.json b/schema/layers/audio-layer.json new file mode 100644 index 00000000..5ba31be6 --- /dev/null +++ b/schema/layers/audio-layer.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Audio Layer", + "description": "A layer playing sounds", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 6 + }, + "au": { + "title": "Audio Settings", + "$ref": "#/$defs/layers/audio-settings" + }, + "refId": { + "title": "Sound Id", + "description": "ID of the sound as specified in the assets", + "type": "string" + } + }, + "required": [ + "ty", "au" + ] + } + ] +} + diff --git a/schema/layers/audio-settings.json b/schema/layers/audio-settings.json new file mode 100644 index 00000000..e123c94e --- /dev/null +++ b/schema/layers/audio-settings.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Audio Settings", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "lv": { + "title": "Level", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "lv" + ] + } + ] +} + + diff --git a/schema/layers/camera-layer.json b/schema/layers/camera-layer.json new file mode 100644 index 00000000..695baa82 --- /dev/null +++ b/schema/layers/camera-layer.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Camera Layer", + "description": "3D Camera", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 13 + }, + "ks": { + "title": "Transform", + "description": "Layer transform", + "$ref": "#/$defs/helpers/transform" + }, + "pe": { + "title": "Perspective", + "description": "Distance from the Z=0 plane.\nSmall values yield a higher perspective effect.", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", "ks", "pe" + ] + } + ] +} + + diff --git a/schema/layers/data-layer.json b/schema/layers/data-layer.json new file mode 100644 index 00000000..19661b53 --- /dev/null +++ b/schema/layers/data-layer.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Data Layer", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 15 + }, + "refId": { + "title": "Data source Id", + "description": "ID of the data source in assets", + "type": "string" + } + }, + "required": [ + "ty" + ] + } + ] +} + diff --git a/schema/layers/image-layer.json b/schema/layers/image-layer.json new file mode 100644 index 00000000..da297928 --- /dev/null +++ b/schema/layers/image-layer.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Image Layer", + "description": "Layer that shows an image asset", + "caniuse": "layer-image", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 2 + }, + "refId": { + "title": "Image Id", + "description": "ID of the image as specified in the assets", + "type": "string", + "default": "" + } + }, + "required": [ + "ty", "refId" + ] + } + ] +} diff --git a/schema/layers/layer.json b/schema/layers/layer.json new file mode 100644 index 00000000..ec7dc12f --- /dev/null +++ b/schema/layers/layer.json @@ -0,0 +1,130 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Layer", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ddd": { + "title": "Threedimensional", + "description": "Whether the layer is threedimensional", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "hd": { + "title": "Hidden", + "description": "Whether the layer is hidden", + "type": "boolean" + }, + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "oneOf": [ + { + "const": 0, + "title": "Precomposition layer" + }, + { + "const": 1, + "title": "Solid color layer" + }, + { + "const": 2, + "title": "Image layer" + }, + { + "const": 3, + "title": "Null layer" + }, + { + "const": 4, + "title": "Shape layer" + }, + { + "const": 5, + "title": "Text layer" + }, + { + "const": 6, + "title": "Audio layer" + }, + { + "const": 7, + "title": "Video placeholder" + }, + { + "const": 8, + "title": "Image sequence" + }, + { + "const": 9, + "title": "Video layer" + }, + { + "const": 10, + "title": "Image placeholder" + }, + { + "const": 11, + "title": "Guide layer" + }, + { + "const": 12, + "title": "Adjustment layer" + }, + { + "const": 13, + "title": "Camera" + }, + { + "const": 14, + "title": "Light layer" + }, + { + "const": 15, + "title": "Data layer" + } + ] + }, + "ind": { + "title": "Index", + "type": "integer", + "description": "Index that can be used for parenting and referenced in expressions" + }, + "parent": { + "title": "Parent Index", + "description": "Must be the `ind` property of another layer", + "type": "integer" + }, + "sr": { + "title": "Time Stretch", + "caniuse": "property-time-stretch", + "type": "number", + "default": 1 + }, + "ip": { + "title": "In Point", + "description": "Frame when the layer becomes visible", + "type": "number" + }, + "op": { + "title": "Out Point", + "description": "Frame when the layer becomes invisible", + "type": "number" + }, + "st": { + "title": "Start Time", + "type": "number", + "default": 0 + } + }, + "required": ["ty", "st", "ip", "op"] + } + ] +} diff --git a/schema/layers/null-layer.json b/schema/layers/null-layer.json new file mode 100644 index 00000000..9ebceb2f --- /dev/null +++ b/schema/layers/null-layer.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Null Layer", + "description": "Layer with no data, useful to group layers together", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 3 + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/layers/precomposition-layer.json b/schema/layers/precomposition-layer.json new file mode 100644 index 00000000..454c430e --- /dev/null +++ b/schema/layers/precomposition-layer.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Precomposition Layer", + "description": "Layer that renders a Precomposition asset", + "caniuse": "layer-precomp", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 0 + }, + "refId": { + "title": "Reference Id", + "description": "ID of the precomp as specified in the assets", + "type": "string" + }, + "w": { + "title": "Width", + "description": "Width of the clipping rect", + "type": "integer" + }, + "h": { + "title": "Height", + "description": "Height of the clipping rect", + "type": "integer" + }, + "tm": { + "title": "Time Remapping", + "caniuse": "property-timeremap", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", "refId", "w", "h" + ] + } + ] +} diff --git a/schema/layers/shape-layer.json b/schema/layers/shape-layer.json new file mode 100644 index 00000000..bcb57603 --- /dev/null +++ b/schema/layers/shape-layer.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Shape Layer", + "description": "Layer containing Shapes", + "caniuse": "layer-shape", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 4 + }, + "shapes": { + "title": "Shapes", + "$ref": "#/$defs/shapes/shape-list" + } + }, + "required": [ + "ty", "shapes" + ] + } + ] +} diff --git a/schema/layers/solid-color-layer.json b/schema/layers/solid-color-layer.json new file mode 100644 index 00000000..bbe36449 --- /dev/null +++ b/schema/layers/solid-color-layer.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Solid Color Layer", + "description": "Layer with a solid color rectangle", + "caniuse": "layer-solid", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 1 + }, + "sc": { + "title": "Color", + "description": "Color of the layer, unlike most other places, the color is a `#rrggbb` hex string", + "type": "string", + "default": "" + }, + "sh": { + "title": "Height", + "type": "number" + }, + "sw": { + "title": "Width", + "type": "number" + } + }, + "required": [ + "ty", "sc", "sw", "sh" + ] + } + ] +} diff --git a/schema/layers/text-layer.json b/schema/layers/text-layer.json new file mode 100644 index 00000000..a53d0232 --- /dev/null +++ b/schema/layers/text-layer.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Layer", + "description": "Layer with some text", + "caniuse": "layer-text", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 5 + }, + "t": { + "title": "Data", + "$ref": "#/$defs/text/text-data" + } + }, + "required": [ + "ty", "t" + ] + } + ] +} diff --git a/schema/layers/visual-layer.json b/schema/layers/visual-layer.json new file mode 100644 index 00000000..c2f80a70 --- /dev/null +++ b/schema/layers/visual-layer.json @@ -0,0 +1,145 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Visual Layer", + "description": "Layer used to affect visual elements", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ks": { + "title": "Transform", + "caniuse": "transform", + "description": "Layer transform", + "$ref": "#/$defs/helpers/transform" + }, + "ao": { + "title": "Auto Orient", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0, + "description": "If 1, The layer will rotate itself to match its animated position path" + }, + "tt": { + "title": "Matte Mode", + "caniuse": "property-matte-mask", + "$ref": "#/$defs/constants/matte-mode", + "description": "Defines the track matte mode for the layer" + }, + "tp": { + "title": "Matte Parent", + "type": "integer", + "description": "Index of the layer used as matte, if omitted assume the layer above the current one" + }, + "td": { + "title": "Matte Target", + "caniuse": "property-matte-mask", + "$ref": "#/$defs/helpers/int-boolean", + "description": "If set to 1, it means a layer is using this layer as a track matte" + }, + "hasMask": { + "title": "Has Masks", + "caniuse": "mask", + "description": "Whether the layer has masks applied", + "type": "boolean" + }, + "masksProperties": { + "title": "Masks", + "caniuse": "mask", + "type": "array", + "items": { + "$ref": "#/$defs/helpers/mask" + } + }, + "ef": { + "title": "Effects", + "description": "List of layer effects", + "caniuse": "effects", + "type": "array", + "items": { + "oneOf": [ + {"$ref": "#/$defs/effects/custom-effect"}, + {"$ref": "#/$defs/effects/drop-shadow-effect"}, + {"$ref": "#/$defs/effects/fill-effect"}, + {"$ref": "#/$defs/effects/gaussian-blur-effect"}, + {"$ref": "#/$defs/effects/matte3-effect"}, + {"$ref": "#/$defs/effects/pro-levels-effect"}, + {"$ref": "#/$defs/effects/stroke-effect"}, + {"$ref": "#/$defs/effects/tint-effect"}, + {"$ref": "#/$defs/effects/tritone-effect"}, + {"$ref": "#/$defs/effects/radial-wipe-effect"}, + {"$ref": "#/$defs/effects/wavy-effect"}, + {"$ref": "#/$defs/effects/puppet-effect"}, + {"$ref": "#/$defs/effects/spherize-effect"}, + {"$ref": "#/$defs/effects/mesh-warp-effect"}, + {"$ref": "#/$defs/effects/displacement-map-effect"}, + {"$ref": "#/$defs/effects/twirl-effect"} + ] + } + }, + "mb": { + "title": "Motion Blur", + "description": "Whether motion blur is enabled for the layer", + "type": "boolean" + }, + "sy": { + "title": "Layer style", + "caniuse": "styles", + "description": "Styling effects for this layer", + "type": "array", + "items": { + "oneOf": [ + {"$ref": "#/$defs/styles/stroke-style"}, + {"$ref": "#/$defs/styles/drop-shadow-style"}, + {"$ref": "#/$defs/styles/inner-shadow-style"}, + {"$ref": "#/$defs/styles/outer-glow-style"}, + {"$ref": "#/$defs/styles/inner-glow-style"}, + {"$ref": "#/$defs/styles/bevel-emboss-style"}, + {"$ref": "#/$defs/styles/satin-style"}, + {"$ref": "#/$defs/styles/color-overlay-style"}, + {"$ref": "#/$defs/styles/gradient-overlay-style"} + ] + } + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/constants/blend-mode", + "default": 0 + }, + "cl": { + "title": "CSS Class", + "description": "CSS class used by the SVG renderer", + "type": "string" + }, + "ln": { + "title": "Layer XML ID", + "description": "`id` attribute used by the SVG renderer", + "type": "string" + }, + "tg": { + "title": "Layer XML tag name", + "description": "tag name used by the SVG renderer", + "type": "string" + }, + "cp": { + "deprecated": true, + "title": "Collapse Transform", + "description": "This is deprecated in favour of `ct`", + "type": "boolean" + }, + "ct": { + "title": "Collapse Transform", + "description": "Marks that transforms should be applied before masks", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + }, + "required": [ + "ks" + ] + } + ] +} + diff --git a/schema/lottie.schema.json b/schema/lottie.schema.json new file mode 100644 index 00000000..e5f9abd3 --- /dev/null +++ b/schema/lottie.schema.json @@ -0,0 +1,5877 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://lottiefiles.github.io/lottie-docs/schema/lottie.schema.json", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/animation/animation" + } + ], + "$defs": { + "animated-properties": { + "color-value": { + "type": "object", + "title": "Color Value", + "description": "An animatable property that holds a Color", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/animated-property" + }, + { + "if": { + "properties": { + "a": { + "const": 0 + } + } + }, + "then": { + "properties": { + "k": { + "title": "Static value", + "$ref": "#/$defs/helpers/color" + } + } + } + } + ] + }, + "shape-keyframe": { + "type": "object", + "title": "Shape Keyframe", + "description": "Keyframe holding Bezier objects", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/keyframe-base" + }, + { + "type": "object", + "properties": { + "s": { + "title": "Start", + "type": "array", + "items": { + "$ref": "#/$defs/helpers/bezier" + } + } + } + } + ] + }, + "position-keyframe": { + "type": "object", + "title": "Position Keyframe", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/keyframe" + }, + { + "properties": { + "ti": { + "title": "Value In Tangent", + "description": "Tangent for values (eg: moving position around a curved path)", + "type": "array", + "items": { + "type": "number" + } + }, + "to": { + "title": "Value Out Tangent", + "description": "Tangent for values (eg: moving position around a curved path)", + "type": "array", + "items": { + "type": "number" + } + } + } + } + ] + }, + "keyframe-bezier-handle": { + "type": "object", + "title": "Keyframe Bezier Handle", + "description": "Bezier handle for keyframe interpolation", + "properties": { + "x": { + "title": "X", + "description": "Time component:\n0 means start time of the keyframe,\n1 means time of the next keyframe.", + "oneOf": [ + { + "type": "array", + "items": { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + }, + "minItems": 1 + }, + { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + } + ] + }, + "y": { + "title": "Y", + "description": "Value interpolation component:\n0 means start value of the keyframe,\n1 means value at the next keyframe.", + "oneOf": [ + { + "type": "array", + "items": { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + }, + "minItems": 1 + }, + { + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 1 + } + ] + } + }, + "required": [ + "x", + "y" + ] + }, + "animated-property": { + "type": "object", + "title": "Animated Property", + "description": "An animatable property that holds an array of numbers", + "allOf": [ + { + "properties": { + "ix": { + "title": "Property Index", + "type": "integer" + }, + "a": { + "title": "Animated", + "description": "Whether the property is animated", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "x": { + "title": "Expression", + "type": "string" + }, + "sid": { + "title": "Slot ID", + "description": "One of the ID in the file's slots", + "type": "string" + } + } + }, + { + "if": { + "properties": { + "a": { + "const": 1 + } + } + }, + "then": { + "properties": { + "k": { + "type": "array", + "title": "Animated Value", + "description": "Array of keyframes", + "items": { + "$ref": "#/$defs/animated-properties/keyframe" + } + } + } + } + } + ], + "required": [ + "k" + ] + }, + "multi-dimensional": { + "type": "object", + "title": "Multi Dimensional", + "description": "An animatable property that holds an array of numbers", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/animated-property" + }, + { + "if": { + "properties": { + "a": { + "const": 0 + } + } + }, + "then": { + "properties": { + "k": { + "title": "Static value", + "type": "array", + "items": { + "type": "number" + } + } + } + }, + "properties": { + "l": { + "title": "Length", + "description": "Number of components in the value arrays.\nIf present values will be truncated or expanded to match this length when accessed from expressions.", + "type": "integer" + } + } + } + ] + }, + "value": { + "type": "object", + "title": "Value", + "description": "An animatable property that holds a float", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/animated-property" + }, + { + "if": { + "properties": { + "a": { + "const": 0 + } + } + }, + "then": { + "properties": { + "k": { + "title": "Static value", + "type": "number" + } + } + } + } + ] + }, + "gradient-colors": { + "type": "object", + "title": "Gradient Colors", + "description": "Represents colors and offsets in a gradient\n\nColors are represented as a flat list interleaving offsets and color components in weird ways\nThere are two possible layouts:\n\nWithout alpha, the colors are a sequence of offset, r, g, b\n\nWith alpha, same as above but at the end of the list there is a sequence of offset, alpha", + "properties": { + "k": { + "title": "Colors", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "p": { + "title": "Count", + "description": "Number of colors in `k`", + "type": "integer", + "default": 0 + } + }, + "required": [ + "p", + "k" + ] + }, + "keyframe": { + "type": "object", + "title": "Keyframe", + "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.", + "allOf": [ + { + "$ref": "#/$defs/animated-properties/keyframe-base" + }, + { + "properties": { + "s": { + "title": "Value", + "description": "Value at this keyframe. Note the if the property is a scalar, keyframe values are still represented as arrays", + "type": "array", + "items": { + "type": "number" + } + }, + "e": { + "title": "End value", + "description": "Value at the end of the keyframe, note that this is deprecated and you should use `s` from the next keyframe to get this value", + "deprecated": true, + "type": "array", + "items": { + "type": "number" + } + } + } + }, + { + "if": { + "oneOf": [ + { + "properties": { + "h": { + "const": 0 + } + } + }, + { + "not": { + "required": [ + "h" + ] + } + } + ] + }, + "then": { + "properties": { + "i": { + "title": "In Tangent", + "description": "Easing tangent going into the next keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + }, + "o": { + "title": "Out Tangent", + "description": "Easing tangent leaving the current keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + } + } + } + } + ], + "required": [ + "t", + "s" + ] + }, + "position": { + "type": "object", + "title": "Position Property", + "description": "An animatable property to represent a position in space", + "allOf": [ + { + "properties": { + "ix": { + "title": "Property Index", + "type": "integer" + }, + "a": { + "title": "Animated", + "description": "Whether the property is animated", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "x": { + "title": "Expression", + "type": "string" + }, + "l": { + "title": "Length", + "description": "Number of components in the value arrays.\nIf present values will be truncated or expanded to match this length when accessed from expressions.", + "type": "integer" + } + } + }, + { + "if": { + "properties": { + "a": { + "const": 1 + } + } + }, + "then": { + "properties": { + "k": { + "type": "array", + "title": "Animated Value", + "description": "Array of keyframes", + "items": { + "$ref": "#/$defs/animated-properties/position-keyframe" + } + } + } + }, + "else": { + "properties": { + "k": { + "title": "Static Value", + "type": "array", + "items": { + "type": "number" + } + } + } + } + } + ], + "required": [ + "k" + ] + }, + "shape-property": { + "type": "object", + "title": "Shape Property", + "description": "An animatable property that holds a Bezier", + "allOf": [ + { + "properties": { + "ix": { + "title": "Property Index", + "type": "integer" + }, + "a": { + "title": "Animated", + "description": "Whether the property is animated", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "x": { + "title": "Expression", + "type": "string" + } + } + }, + { + "if": { + "properties": { + "a": { + "const": 1 + } + } + }, + "then": { + "properties": { + "k": { + "type": "array", + "title": "Animated Value", + "description": "Array of keyframes", + "items": { + "$ref": "#/$defs/animated-properties/shape-keyframe" + } + } + } + }, + "else": { + "properties": { + "k": { + "$ref": "#/$defs/helpers/bezier", + "title": "Static Value" + } + } + } + } + ], + "required": [ + "k" + ] + }, + "keyframe-base": { + "type": "object", + "title": "Base Keyframe", + "description": "A Keyframes specifies the value at a specific time and the interpolation function to reach the next keyframe.", + "allOf": [ + { + "properties": { + "t": { + "title": "Time", + "type": "number", + "default": 0 + }, + "h": { + "title": "Hold", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + } + }, + { + "if": { + "oneOf": [ + { + "properties": { + "h": { + "const": 0 + } + } + }, + { + "not": { + "required": [ + "h" + ] + } + } + ] + }, + "then": { + "properties": { + "i": { + "title": "In Tangent", + "description": "Easing tangent going into the next keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + }, + "o": { + "title": "Out Tangent", + "description": "Easing tangent leaving the current keyframe", + "$ref": "#/$defs/animated-properties/keyframe-bezier-handle" + } + } + } + } + ], + "required": [ + "t", + "s" + ] + }, + "split-vector": { + "type": "object", + "title": "Split Vector", + "description": "An animatable property that is split into individually anaimated components", + "properties": { + "s": { + "title": "Split", + "type": "boolean", + "const": true + }, + "x": { + "title": "X", + "$ref": "#/$defs/animated-properties/value" + }, + "y": { + "title": "Y", + "$ref": "#/$defs/animated-properties/value" + }, + "z": { + "title": "Z", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "s", + "x", + "y" + ] + } + }, + "animation": { + "motion-blur": { + "type": "object", + "title": "Motion Blur", + "description": "Motion blur settings", + "properties": { + "sa": { + "title": "Shutter Angle", + "description": "Angle in degrees", + "type": "number" + }, + "sp": { + "title": "Shutter Phase", + "description": "Angle in degrees", + "type": "number" + }, + "spf": { + "title": "Samples per Frame", + "type": "number" + }, + "asl": { + "title": "Adaptive Sample Limit", + "type": "number" + } + } + }, + "animation": { + "type": "object", + "title": "Animation", + "description": "Top level object, describing the animation", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "v": { + "title": "Version", + "type": "string", + "default": "5.5.2" + }, + "fr": { + "title": "Framerate", + "description": "Framerate in frames per second", + "type": "number", + "default": 60 + }, + "ip": { + "title": "In Point", + "description": "\"In Point\", which frame the animation starts at (usually 0)", + "type": "number", + "default": 0 + }, + "op": { + "title": "Out Point", + "description": "\"Out Point\", which frame the animation stops/loops at, which makes this the duration in frames when `ip` is 0", + "type": "number", + "default": 60 + }, + "w": { + "title": "Width", + "description": "Width of the animation", + "type": "integer", + "default": 512 + }, + "h": { + "title": "Height", + "description": "Height of the animation", + "type": "integer", + "default": 512 + }, + "ddd": { + "title": "Threedimensional", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0, + "description": "Whether the animation has 3D layers" + }, + "assets": { + "title": "Assets", + "type": "array", + "description": "List of assets that can be referenced by layers", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/assets/image" + }, + { + "$ref": "#/$defs/assets/precomposition" + }, + { + "$ref": "#/$defs/assets/sound" + }, + { + "$ref": "#/$defs/assets/data-source" + } + ] + } + }, + "comps": { + "title": "Extra Compositions", + "type": "array", + "description": "List of Extra compositions not referenced by anything", + "items": { + "$ref": "#/$defs/assets/precomposition" + } + }, + "fonts": { + "title": "Fonts", + "$ref": "#/$defs/text/font-list" + }, + "chars": { + "title": "Characters", + "description": "Data defining text characters as lottie shapes. If present a player might only render characters defined here and nothing else.", + "type": "array", + "items": { + "$ref": "#/$defs/text/character-data" + } + }, + "meta": { + "title": "Metadata", + "description": "Document metadata", + "$ref": "#/$defs/animation/metadata" + }, + "metadata": { + "title": "User Metadata", + "$ref": "#/$defs/animation/user-metadata" + }, + "markers": { + "title": "Markers", + "description": "Markers defining named sections of the composition.", + "type": "array", + "items": { + "$ref": "#/$defs/helpers/marker" + } + }, + "mb": { + "title": "Motion Blur", + "$ref": "#/$defs/animation/motion-blur" + }, + "slots": { + "title": "Slots", + "description": "Available property overrides", + "type": "object", + "patternProperties": { + ".*": { + "p": { + "anyOf": [ + { + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + { + "$ref": "#/$defs/animated-properties/color-value" + }, + { + "$ref": "#/$defs/animated-properties/position" + }, + { + "$ref": "#/$defs/animated-properties/shape-property" + }, + { + "$ref": "#/$defs/animated-properties/value" + }, + { + "$ref": "#/$defs/assets/image" + }, + { + "$ref": "#/$defs/text/animated-text-document" + } + ] + }, + "required": [ + "p" + ] + } + } + } + }, + "required": [ + "w", + "h", + "fr", + "layers", + "op", + "ip" + ] + }, + { + "$ref": "#/$defs/animation/composition" + } + ] + }, + "composition": { + "type": "object", + "title": "Composition", + "description": "Base class for layer holders", + "properties": { + "layers": { + "title": "Layers", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/layers/precomposition-layer" + }, + { + "$ref": "#/$defs/layers/solid-color-layer" + }, + { + "$ref": "#/$defs/layers/image-layer" + }, + { + "$ref": "#/$defs/layers/null-layer" + }, + { + "$ref": "#/$defs/layers/shape-layer" + }, + { + "$ref": "#/$defs/layers/text-layer" + }, + { + "$ref": "#/$defs/layers/audio-layer" + }, + { + "$ref": "#/$defs/layers/camera-layer" + }, + { + "$ref": "#/$defs/layers/data-layer" + } + ] + } + } + }, + "required": [ + "layers" + ] + }, + "user-metadata": { + "type": "object", + "title": "User Metadata", + "description": "User-defined metadata", + "properties": { + "filename": { + "title": "Filename", + "type": "string" + }, + "customProps": { + "title": "Custom Properties", + "type": "object" + } + } + }, + "metadata": { + "type": "object", + "title": "Metadata", + "description": "Document metadata", + "properties": { + "a": { + "title": "Author", + "type": "string" + }, + "d": { + "title": "Description", + "type": "string" + }, + "tc": { + "title": "Theme Color", + "type": "string" + }, + "g": { + "title": "Generator", + "description": "Software used to generate the file", + "type": "string" + } + }, + "anyOf": [ + { + "properties": { + "k": { + "title": "Keywords", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + { + "properties": { + "k": { + "title": "Keywords", + "type": "string" + } + } + } + ] + } + }, + "assets": { + "data-source": { + "type": "object", + "title": "Data source", + "description": "External data source, usually a JSON file", + "allOf": [ + { + "$ref": "#/$defs/assets/file-asset" + }, + { + "type": "object", + "properties": { + "t": { + "title": "Type", + "type": "integer", + "const": 3 + } + }, + "required": [ + "t" + ] + } + ] + }, + "sound": { + "type": "object", + "title": "Sound", + "description": "External sound", + "allOf": [ + { + "$ref": "#/$defs/assets/file-asset" + } + ] + }, + "image": { + "type": "object", + "title": "Image", + "description": "External image", + "allOf": [ + { + "$ref": "#/$defs/assets/file-asset" + }, + { + "type": "object", + "properties": { + "w": { + "title": "Width", + "description": "Width of the image", + "type": "number", + "default": 0 + }, + "h": { + "title": "Height", + "description": "Height of the image", + "type": "number", + "default": 0 + }, + "t": { + "title": "Type", + "description": "Marks as part of an image sequence if present", + "type": "string", + "const": "seq" + }, + "sid": { + "title": "Slot ID", + "description": "One of the ID in the file's slots", + "type": "string" + } + }, + "required": [ + "p" + ] + } + ] + }, + "file-asset": { + "type": "object", + "title": "File Asset", + "description": "Asset referencing a file", + "allOf": [ + { + "$ref": "#/$defs/assets/asset" + }, + { + "type": "object", + "properties": { + "u": { + "title": "Path", + "description": "Path to the directory containing a file", + "type": "string", + "default": "" + }, + "p": { + "title": "File name", + "description": "Filename or data url", + "type": "string", + "default": "" + }, + "e": { + "title": "Embedded", + "description": "Whether the file is embedded", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + }, + "required": [ + "p" + ] + } + ] + }, + "asset": { + "type": "object", + "title": "Asset", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "id": { + "title": "ID", + "description": "Unique identifier used by layers when referencing this asset", + "type": "string", + "default": "" + }, + "nm": { + "title": "Name", + "description": "Human readable name", + "type": "string" + } + }, + "required": [ + "id" + ] + } + ] + }, + "precomposition": { + "type": "object", + "title": "Precomposition", + "description": "Asset containing an animation that can be referenced by layers.", + "allOf": [ + { + "$ref": "#/$defs/assets/asset" + }, + { + "$ref": "#/$defs/animation/composition" + }, + { + "type": "object", + "properties": { + "fr": { + "title": "Framerate", + "description": "Framerate in frames per second", + "type": "number" + }, + "xt": { + "title": "Extra", + "description": "Extra composition", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + } + } + ] + } + }, + "constants": { + "trim-multiple-shapes": { + "type": "integer", + "title": "Trim Multiple Shapes", + "description": "How to handle multiple shapes in trim path", + "oneOf": [ + { + "title": "Simultaneously", + "const": 1 + }, + { + "title": "Individually", + "const": 2 + } + ] + }, + "stroke-dash-type": { + "type": "string", + "title": "Stroke Dash Type", + "description": "Type of a dash item in a stroked line", + "oneOf": [ + { + "title": "Dash", + "const": "d" + }, + { + "title": "Gap", + "const": "g" + }, + { + "title": "Offset", + "const": "o" + } + ] + }, + "shape-direction": { + "type": "integer", + "title": "Shape Direction", + "description": "Drawing direction of the shape curve, useful for trim path", + "oneOf": [ + { + "title": "Normal", + "description": "Usually clockwise", + "const": 1 + }, + { + "title": "Reversed", + "description": "Usually counter clockwise", + "const": 3 + } + ] + }, + "text-shape": { + "type": "integer", + "title": "Text Shape", + "description": "Defines the function used to determine the interpolating factor on a text range selector.", + "oneOf": [ + { + "title": "Square", + "const": 1 + }, + { + "title": "Ramp Up", + "const": 2 + }, + { + "title": "Ramp Down", + "const": 3 + }, + { + "title": "Triangle", + "const": 4 + }, + { + "title": "Round", + "const": 5 + }, + { + "title": "Smooth", + "const": 6 + } + ] + }, + "text-range-units": { + "type": "integer", + "title": "Text Range Units", + "description": "Unit type for a text selector", + "oneOf": [ + { + "title": "Percent", + "const": 1 + }, + { + "title": "Index", + "const": 2 + } + ] + }, + "text-grouping": { + "type": "integer", + "title": "Text Grouping", + "description": "", + "oneOf": [ + { + "title": "Characters", + "const": 1 + }, + { + "title": "Word", + "const": 2 + }, + { + "title": "Line", + "const": 3 + }, + { + "title": "All", + "const": 4 + } + ] + }, + "composite": { + "type": "integer", + "title": "Composite", + "description": "How to stack copies in a repeater", + "oneOf": [ + { + "title": "Below", + "description": "Subsequent copies are added underneath the previous ones.", + "const": 1 + }, + { + "title": "Above", + "description": "Subsequent copies are added on top of the previous ones.", + "const": 2 + } + ] + }, + "mask-mode": { + "type": "string", + "title": "Mask Mode", + "description": "How masks interact with each other. See https://helpx.adobe.com/after-effects/using/alpha-channels-masks-mattes.html", + "oneOf": [ + { + "title": "None", + "const": "n" + }, + { + "title": "Add", + "const": "a" + }, + { + "title": "Subtract", + "const": "s" + }, + { + "title": "Intersect", + "const": "i" + }, + { + "title": "Lighten", + "const": "l" + }, + { + "title": "Darken", + "const": "d" + }, + { + "title": "Difference", + "const": "f" + } + ] + }, + "line-join": { + "type": "integer", + "title": "Line Join", + "description": "Style at a sharp corner of a stoked line", + "oneOf": [ + { + "title": "Miter", + "const": 1 + }, + { + "title": "Round", + "const": 2 + }, + { + "title": "Bevel", + "const": 3 + } + ] + }, + "font-path-origin": { + "type": "integer", + "title": "Font Path Origin", + "description": "", + "oneOf": [ + { + "title": "Local", + "const": 0 + }, + { + "title": "Css Url", + "const": 1 + }, + { + "title": "Script Url", + "const": 2 + }, + { + "title": "Font Url", + "const": 3 + } + ] + }, + "line-cap": { + "type": "integer", + "title": "Line Cap", + "description": "Style at the end of a stoked line", + "oneOf": [ + { + "title": "Butt", + "const": 1 + }, + { + "title": "Round", + "const": 2 + }, + { + "title": "Square", + "const": 3 + } + ] + }, + "gradient-type": { + "type": "integer", + "title": "Gradient Type", + "description": "Type of a gradient", + "oneOf": [ + { + "title": "Linear", + "type": "integer", + "const": 1 + }, + { + "title": "Radial", + "type": "integer", + "const": 2 + } + ] + }, + "merge-mode": { + "type": "integer", + "title": "Merge Mode", + "description": "Boolean operation on shapes", + "oneOf": [ + { + "title": "Normal", + "const": 1 + }, + { + "title": "Add", + "const": 2 + }, + { + "title": "Subtract", + "const": 3 + }, + { + "title": "Intersect", + "const": 4 + }, + { + "title": "Exclude Intersections", + "const": 5 + } + ] + }, + "fill-rule": { + "type": "integer", + "title": "Fill Rule", + "description": "Rule used to handle multiple shapes rendered with the same fill object", + "oneOf": [ + { + "title": "Non Zero", + "description": "Everything is colored (You can think of this as an OR)", + "const": 1 + }, + { + "title": "Even Odd", + "description": "Colored based on intersections and path direction, can be used to create \"holes\"", + "const": 2 + } + ] + }, + "text-caps": { + "type": "integer", + "title": "Text Caps", + "oneOf": [ + { + "title": "Regular", + "const": 0 + }, + { + "title": "All Caps", + "const": 1 + }, + { + "title": "Small Caps", + "const": 2 + } + ], + "default": 0 + }, + "blend-mode": { + "type": "integer", + "title": "Blend Mode", + "description": "Layer and shape blend mode", + "caniuse": "blend-mode", + "oneOf": [ + { + "title": "Normal", + "const": 0 + }, + { + "title": "Multiply", + "const": 1 + }, + { + "title": "Screen", + "const": 2 + }, + { + "title": "Overlay", + "const": 3 + }, + { + "title": "Darken", + "const": 4 + }, + { + "title": "Lighten", + "const": 5 + }, + { + "title": "Color Dodge", + "const": 6 + }, + { + "title": "Color Burn", + "const": 7 + }, + { + "title": "Hard Light", + "const": 8 + }, + { + "title": "Soft Light", + "const": 9 + }, + { + "title": "Difference", + "const": 10 + }, + { + "title": "Exclusion", + "const": 11 + }, + { + "title": "Hue", + "const": 12 + }, + { + "title": "Saturation", + "const": 13 + }, + { + "title": "Color", + "const": 14 + }, + { + "title": "Luminosity", + "const": 15 + }, + { + "title": "Add", + "const": 16 + }, + { + "title": "Hard Mix", + "const": 17 + } + ] + }, + "text-justify": { + "type": "integer", + "title": "Text Justify", + "description": "Text alignment / justification", + "oneOf": [ + { + "title": "Left", + "const": 0 + }, + { + "title": "Right", + "const": 1 + }, + { + "title": "Center", + "const": 2 + }, + { + "title": "Justify with Last Line Left", + "const": 3 + }, + { + "title": "Justify with Last Line Right", + "const": 4 + }, + { + "title": "Justify with Last Line Center", + "const": 5 + }, + { + "title": "Justify with Last Line Full", + "const": 6 + } + ] + }, + "matte-mode": { + "type": "integer", + "title": "Matte Mode", + "description": "How a layer should mask another layer", + "oneOf": [ + { + "title": "Normal", + "const": 0 + }, + { + "title": "Alpha", + "const": 1 + }, + { + "title": "Inverted Alpha", + "const": 2 + }, + { + "title": "Luma", + "const": 3 + }, + { + "title": "Inverted Luma", + "const": 4 + } + ] + }, + "text-based": { + "type": "integer", + "title": "Text Based", + "description": "", + "oneOf": [ + { + "title": "Characters", + "const": 1 + }, + { + "title": "Character Excluding Spaces", + "const": 2 + }, + { + "title": "Words", + "const": 3 + }, + { + "title": "Lines", + "const": 4 + } + ] + }, + "star-type": { + "type": "integer", + "title": "Star Type", + "description": "Star or Polygon", + "oneOf": [ + { + "title": "Star", + "const": 1 + }, + { + "title": "Polygon", + "const": 2 + } + ] + } + }, + "effect-values": { + "checkbox": { + "type": "object", + "title": "Effect Value Checkbox", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 4 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "angle": { + "type": "object", + "title": "Effect Value Angle", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 1 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "drop-down": { + "type": "object", + "title": "Effect Value Drop Down", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 7 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "slider": { + "type": "object", + "title": "Effect Value Slider", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 0 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "point": { + "type": "object", + "title": "Effect Value Point", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 3 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "ignored": { + "type": "object", + "title": "Ignored Value", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 6 + }, + "v": { + "title": "Value", + "type": "number", + "default": 0 + } + }, + "required": [ + "ty" + ] + } + ] + }, + "no-value": { + "type": "object", + "title": "Effect No Value", + "description": "" + }, + "effect-value": { + "type": "object", + "title": "Effect Value", + "description": "Value for an effect", + "caniuse": "effects", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ix": { + "title": "Effect Index", + "type": "integer" + }, + "mn": { + "title": "Match Name", + "type": "string" + }, + "nm": { + "title": "Name", + "type": "string" + }, + "ty": { + "title": "Type", + "type": "integer" + } + }, + "required": [] + } + ] + }, + "color": { + "type": "object", + "title": "Effect Value Color", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 2 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/color-value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "layer": { + "type": "object", + "title": "Effect Value Layer", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effect-values/effect-value" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 10 + }, + "v": { + "title": "Value", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + } + }, + "effects": { + "gaussian-blur-effect": { + "type": "object", + "title": "Gaussian Blur Effect", + "description": "Gaussian blur", + "caniuse": "effect-gaussian-blur", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 29 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "sigma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "direction", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "wrap", + "$ref": "#/$defs/effect-values/checkbox" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "drop-shadow-effect": { + "type": "object", + "title": "Drop Shadow Effect", + "description": "Adds a shadow to the layer", + "caniuse": "effect-drop-shadow", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 25 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "color", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "opacity", + "description": "Opacity between 0 and 255", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "angle", + "$ref": "#/$defs/effect-values/angle" + }, + { + "title": "distance", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "blur", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "tint-effect": { + "type": "object", + "title": "Tint Effect", + "description": "Colorizes the layer", + "caniuse": "effect-tint", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 20 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Black Color", + "description": "Tint of the darker parts of the layer", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "White Color", + "description": "Tint of the lighter parts of the layer", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "Intensity", + "description": "Intensity of the effect, 0 means the layer is unchanged. 100 means full effect", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "custom-effect": { + "type": "object", + "title": "Custom Effect", + "description": "Some lottie files use `ty` = 5 for many different effects", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 5 + } + }, + "required": [ + "ty" + ] + } + ] + }, + "spherize-effect": { + "type": "object", + "title": "Spherize Effect", + "description": "", + "caniuse": "effect-cc-sphere", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 33 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "radius", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "center", + "$ref": "#/$defs/effect-values/point" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "twirl-effect": { + "type": "object", + "title": "Twirl Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 30 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Angle", + "$ref": "#/$defs/effect-values/angle" + }, + { + "title": "Radius", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Center", + "$ref": "#/$defs/effect-values/point" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] + }, + "tritone-effect": { + "type": "object", + "title": "Tritone Effect", + "description": "Maps layers colors based on bright/mid/dark colors", + "caniuse": "effect-tritone", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 23 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "bright", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "mid", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "dark", + "$ref": "#/$defs/effect-values/color" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "displacement-map-effect": { + "type": "object", + "title": "Displacement Map Effect", + "description": "", + "caniuse": "effect-displacement-map", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 27 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Displacement Map Layer", + "$ref": "#/$defs/effect-values/layer" + }, + { + "title": "Use For Horizontal Displacement", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Max Horizontal Displacement", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Use For Vertical Displacement", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Max Vertical Displacement", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Displacement Map Behavior", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Edge Behavior", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Expand Output", + "$ref": "#/$defs/effect-values/drop-down" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] + }, + "radial-wipe-effect": { + "type": "object", + "title": "Radial Wipe", + "caniuse": "effect-radial-wipe", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 26 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Completion", + "description": "Between 0 and 100", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Start Angle", + "$ref": "#/$defs/effect-values/angle" + }, + { + "title": "Wipe Center", + "$ref": "#/$defs/effect-values/point" + }, + { + "title": "Wipe", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Feather", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "matte3-effect": { + "type": "object", + "title": "Set Matte Effect", + "description": "Uses a layer as a mask", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 28 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Layer", + "description": "Use this layer as a mask", + "$ref": "#/$defs/effect-values/layer" + }, + { + "title": "Channel", + "description": "Channel to use as a mask:\n1 - Red\n2 - Green\n3 - Blue\n4 - Alpha\n5 - Luminance\n6 - Hue\n7 - Lightness\n8 - Saturation\n9 - Full\n10 - Off", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Invert", + "description": "Use 0 as opaque value when true", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Stretch To Fit", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Show Mask", + "description": "If false, the mask layer won't be shown", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Premultiply Mask", + "$ref": "#/$defs/effect-values/drop-down" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "puppet-effect": { + "type": "object", + "title": "Puppet Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 34 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Puppet Engine", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Mesh Rotation Refinement", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "On Transparent", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "03", + "$ref": "#/$defs/effect-values/no-value" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] + }, + "stroke-effect": { + "type": "object", + "title": "Stroke Effect", + "description": "", + "caniuse": "effect-stroke", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 22 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "00", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "01", + "$ref": "#/$defs/effect-values/checkbox" + }, + { + "title": "02", + "$ref": "#/$defs/effect-values/checkbox" + }, + { + "title": "color", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "04", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "05", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "06", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "07", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "08", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "09", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "type", + "$ref": "#/$defs/effect-values/drop-down" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "pro-levels-effect": { + "type": "object", + "title": "Pro Levels Effect", + "description": "", + "caniuse": "effect-color-levels-individual-controls", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 24 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "00", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "01", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "02", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "comp_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "comp_outwhite", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "08", + "$ref": "#/$defs/effect-values/no-value" + }, + { + "title": "09", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "r_outwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "15", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "16", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "g_outwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "22", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "23", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "b_outwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "29", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_inblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_inwhite", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_gamma", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_outblack", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "a_outwhite", + "$ref": "#/$defs/effect-values/no-value" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + }, + "effect": { + "type": "object", + "title": "Effect", + "description": "Layer effect", + "caniuse": "effects", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ef": { + "title": "Effect Values", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/effect-values/no-value" + }, + { + "$ref": "#/$defs/effect-values/angle" + }, + { + "$ref": "#/$defs/effect-values/checkbox" + }, + { + "$ref": "#/$defs/effect-values/color" + }, + { + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "$ref": "#/$defs/effect-values/ignored" + }, + { + "$ref": "#/$defs/effect-values/layer" + }, + { + "$ref": "#/$defs/effect-values/point" + }, + { + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "np": { + "title": "Property Count", + "description": "Number of values in `ef`", + "type": "integer" + }, + "ix": { + "title": "Effect Index", + "type": "integer" + }, + "ty": { + "title": "Type", + "description": "Effect type", + "type": "integer" + }, + "en": { + "title": "Enabled", + "$ref": "#/$defs/helpers/int-boolean", + "default": 1 + } + }, + "required": [ + "ty", + "ef" + ] + } + ] + }, + "wavy-effect": { + "type": "object", + "title": "Wavy Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 32 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Radius", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Center", + "$ref": "#/$defs/effect-values/point" + }, + { + "title": "Conversion type", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Speed", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "Width", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Height", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Phase", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] + }, + "mesh-warp-effect": { + "type": "object", + "title": "Mesh Warp Effect", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 31 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "Rows", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Columns", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "Quality", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "03", + "$ref": "#/$defs/effect-values/no-value" + } + ] + } + }, + "required": [ + "ty", + "ef" + ] + } + ] + }, + "fill-effect": { + "type": "object", + "title": "Fill Effect", + "description": "Replaces the whole layer with the given color", + "caniuse": "effect-fill", + "allOf": [ + { + "$ref": "#/$defs/effects/effect" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "type": "integer", + "const": 21 + }, + "ef": { + "title": "Effect values", + "type": "array", + "prefixItems": [ + { + "title": "00", + "$ref": "#/$defs/effect-values/point" + }, + { + "title": "01", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "color", + "$ref": "#/$defs/effect-values/color" + }, + { + "title": "03", + "$ref": "#/$defs/effect-values/drop-down" + }, + { + "title": "04", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "05", + "$ref": "#/$defs/effect-values/slider" + }, + { + "title": "opacity", + "description": "Opacity in [0, 1]", + "$ref": "#/$defs/effect-values/slider" + } + ] + } + }, + "required": [ + "ty" + ] + } + ] + } + }, + "helpers": { + "mask": { + "type": "object", + "title": "Mask", + "caniuse": "mask", + "description": "Bezier shape used to mask/clip a layer", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "inv": { + "title": "Inverted", + "caniuse": "mask-inverted", + "type": "boolean", + "default": false + }, + "pt": { + "title": "Shape", + "$ref": "#/$defs/animated-properties/shape-property" + }, + "o": { + "title": "Opacity", + "caniuse": "mask-opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "mode": { + "title": "Mode", + "caniuse": "mask-modes", + "$ref": "#/$defs/constants/mask-mode", + "default": "i" + }, + "x": { + "title": "Expand", + "caniuse": "mask-expansion", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] + }, + "transform": { + "type": "object", + "title": "Transform", + "description": "Layer transform", + "allOf": [ + { + "properties": { + "a": { + "title": "Anchor Point", + "caniuse": "transform-anchor-point", + "description": "Anchor point: a position (relative to its parent) around which transformations are applied (ie: center for rotation / scale)", + "$ref": "#/$defs/animated-properties/position" + }, + "s": { + "title": "Scale", + "caniuse": "transform-scale", + "description": "Scale factor, `[100, 100]` for no scaling", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "o": { + "title": "Opacity", + "caniuse": "transform-opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "sk": { + "title": "Skew", + "caniuse": "transform-skew", + "description": "Skew amount as an angle in degrees", + "$ref": "#/$defs/animated-properties/value" + }, + "sa": { + "title": "Skew Axis", + "caniuse": "transform-skew", + "description": "Direction along which skew is applied, in degrees (`0` skews along the X axis, `90` along the Y axis)", + "$ref": "#/$defs/animated-properties/value" + } + } + }, + { + "anyOf": [ + { + "oneOf": [ + { + "properties": { + "p": { + "title": "Position", + "caniuse": "transform-position", + "description": "Position / Translation", + "$ref": "#/$defs/animated-properties/position" + } + } + }, + { + "properties": { + "p": { + "title": "Position", + "description": "Position / Translation with split components", + "$ref": "#/$defs/animated-properties/split-vector" + } + } + } + ] + }, + { + "oneOf": [ + { + "properties": { + "r": { + "title": "Rotation", + "caniuse": "transform-rotation", + "description": "Rotation in degrees, clockwise", + "$ref": "#/$defs/animated-properties/value" + } + } + }, + { + "properties": { + "rx": { + "title": "X Rotation", + "description": "Split rotation component", + "$ref": "#/$defs/animated-properties/value" + }, + "ry": { + "title": "Y Rotation", + "description": "Split rotation component", + "$ref": "#/$defs/animated-properties/value" + }, + "rz": { + "title": "Z Rotation", + "description": "Split rotation component, equivalent to `r` when not split", + "$ref": "#/$defs/animated-properties/value" + }, + "or": { + "title": "Orientation", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + } + } + ] + } + ] + } + ] + }, + "bezier": { + "type": "object", + "title": "Bezier", + "description": "Single bezier curve", + "properties": { + "c": { + "title": "Closed", + "type": "boolean", + "default": false + }, + "i": { + "title": "In Tangents", + "type": "array", + "description": "Array of points, each point is an array of coordinates.\nThese points are along the `in` tangents relative to the corresponding `v`.", + "items": { + "type": "array", + "items": { + "type": "number", + "default": [] + } + } + }, + "o": { + "title": "Out Tangents", + "type": "array", + "description": "Array of points, each point is an array of coordinates.\nThese points are along the `out` tangents relative to the corresponding `v`.", + "items": { + "type": "array", + "items": { + "type": "number", + "default": [] + } + } + }, + "v": { + "title": "Vertices", + "description": "Array of points, each point is an array of coordinates.\nThese points are along the bezier path", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number", + "default": [] + } + } + } + }, + "required": [ + "i", + "v", + "o" + ] + }, + "visual-object": { + "type": "object", + "title": "Visual Object", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "nm": { + "title": "Name", + "description": "Name, as seen from editors and the like", + "type": "string" + }, + "mn": { + "title": "Match Name", + "description": "Match name, used in expressions", + "type": "string" + } + }, + "required": [] + } + ] + }, + "color": { + "type": "array", + "title": "Color", + "description": "Color as a [r, g, b] array with values in [0, 1]", + "items": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "minItems": 3, + "maxItems": 4 + }, + "marker": { + "type": "object", + "title": "Marker", + "description": "Defines named portions of the composition.", + "properties": { + "cm": { + "title": "Comment", + "type": "string" + }, + "tm": { + "title": "Time", + "type": "number" + }, + "dr": { + "title": "Duration", + "type": "number" + } + } + }, + "int-boolean": { + "type": "integer", + "title": "Integer Boolean", + "description": "Represents boolean values as an integer. 0 is false, 1 is true.", + "default": 0, + "examples": [ + 0 + ], + "enum": [ + 0, + 1 + ], + "oneOf": [ + { + "title": "True", + "const": 1 + }, + { + "title": "False", + "const": 0 + } + ] + } + }, + "layers": { + "null-layer": { + "type": "object", + "title": "Null Layer", + "description": "Layer with no data, useful to group layers together", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 3 + } + }, + "required": [ + "ty" + ] + } + ] + }, + "audio-settings": { + "type": "object", + "title": "Audio Settings", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "lv": { + "title": "Level", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "lv" + ] + } + ] + }, + "audio-layer": { + "type": "object", + "title": "Audio Layer", + "description": "A layer playing sounds", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 6 + }, + "au": { + "title": "Audio Settings", + "$ref": "#/$defs/layers/audio-settings" + }, + "refId": { + "title": "Sound Id", + "description": "ID of the sound as specified in the assets", + "type": "string" + } + }, + "required": [ + "ty", + "au" + ] + } + ] + }, + "image-layer": { + "type": "object", + "title": "Image Layer", + "description": "Layer that shows an image asset", + "caniuse": "layer-image", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 2 + }, + "refId": { + "title": "Image Id", + "description": "ID of the image as specified in the assets", + "type": "string", + "default": "" + } + }, + "required": [ + "ty", + "refId" + ] + } + ] + }, + "camera-layer": { + "type": "object", + "title": "Camera Layer", + "description": "3D Camera", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 13 + }, + "ks": { + "title": "Transform", + "description": "Layer transform", + "$ref": "#/$defs/helpers/transform" + }, + "pe": { + "title": "Perspective", + "description": "Distance from the Z=0 plane.\nSmall values yield a higher perspective effect.", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", + "ks", + "pe" + ] + } + ] + }, + "visual-layer": { + "type": "object", + "title": "Visual Layer", + "description": "Layer used to affect visual elements", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ks": { + "title": "Transform", + "caniuse": "transform", + "description": "Layer transform", + "$ref": "#/$defs/helpers/transform" + }, + "ao": { + "title": "Auto Orient", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0, + "description": "If 1, The layer will rotate itself to match its animated position path" + }, + "tt": { + "title": "Matte Mode", + "caniuse": "property-matte-mask", + "$ref": "#/$defs/constants/matte-mode", + "description": "Defines the track matte mode for the layer" + }, + "tp": { + "title": "Matte Parent", + "type": "integer", + "description": "Index of the layer used as matte, if omitted assume the layer above the current one" + }, + "td": { + "title": "Matte Target", + "caniuse": "property-matte-mask", + "$ref": "#/$defs/helpers/int-boolean", + "description": "If set to 1, it means a layer is using this layer as a track matte" + }, + "hasMask": { + "title": "Has Masks", + "caniuse": "mask", + "description": "Whether the layer has masks applied", + "type": "boolean" + }, + "masksProperties": { + "title": "Masks", + "caniuse": "mask", + "type": "array", + "items": { + "$ref": "#/$defs/helpers/mask" + } + }, + "ef": { + "title": "Effects", + "description": "List of layer effects", + "caniuse": "effects", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/effects/custom-effect" + }, + { + "$ref": "#/$defs/effects/drop-shadow-effect" + }, + { + "$ref": "#/$defs/effects/fill-effect" + }, + { + "$ref": "#/$defs/effects/gaussian-blur-effect" + }, + { + "$ref": "#/$defs/effects/matte3-effect" + }, + { + "$ref": "#/$defs/effects/pro-levels-effect" + }, + { + "$ref": "#/$defs/effects/stroke-effect" + }, + { + "$ref": "#/$defs/effects/tint-effect" + }, + { + "$ref": "#/$defs/effects/tritone-effect" + }, + { + "$ref": "#/$defs/effects/radial-wipe-effect" + }, + { + "$ref": "#/$defs/effects/wavy-effect" + }, + { + "$ref": "#/$defs/effects/puppet-effect" + }, + { + "$ref": "#/$defs/effects/spherize-effect" + }, + { + "$ref": "#/$defs/effects/mesh-warp-effect" + }, + { + "$ref": "#/$defs/effects/displacement-map-effect" + }, + { + "$ref": "#/$defs/effects/twirl-effect" + } + ] + } + }, + "mb": { + "title": "Motion Blur", + "description": "Whether motion blur is enabled for the layer", + "type": "boolean" + }, + "sy": { + "title": "Layer style", + "caniuse": "styles", + "description": "Styling effects for this layer", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/styles/stroke-style" + }, + { + "$ref": "#/$defs/styles/drop-shadow-style" + }, + { + "$ref": "#/$defs/styles/inner-shadow-style" + }, + { + "$ref": "#/$defs/styles/outer-glow-style" + }, + { + "$ref": "#/$defs/styles/inner-glow-style" + }, + { + "$ref": "#/$defs/styles/bevel-emboss-style" + }, + { + "$ref": "#/$defs/styles/satin-style" + }, + { + "$ref": "#/$defs/styles/color-overlay-style" + }, + { + "$ref": "#/$defs/styles/gradient-overlay-style" + } + ] + } + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/constants/blend-mode", + "default": 0 + }, + "cl": { + "title": "CSS Class", + "description": "CSS class used by the SVG renderer", + "type": "string" + }, + "ln": { + "title": "Layer XML ID", + "description": "`id` attribute used by the SVG renderer", + "type": "string" + }, + "tg": { + "title": "Layer XML tag name", + "description": "tag name used by the SVG renderer", + "type": "string" + }, + "cp": { + "deprecated": true, + "title": "Collapse Transform", + "description": "This is deprecated in favour of `ct`", + "type": "boolean" + }, + "ct": { + "title": "Collapse Transform", + "description": "Marks that transforms should be applied before masks", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + } + }, + "required": [ + "ks" + ] + } + ] + }, + "solid-color-layer": { + "type": "object", + "title": "Solid Color Layer", + "description": "Layer with a solid color rectangle", + "caniuse": "layer-solid", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 1 + }, + "sc": { + "title": "Color", + "description": "Color of the layer, unlike most other places, the color is a `#rrggbb` hex string", + "type": "string", + "default": "" + }, + "sh": { + "title": "Height", + "type": "number" + }, + "sw": { + "title": "Width", + "type": "number" + } + }, + "required": [ + "ty", + "sc", + "sw", + "sh" + ] + } + ] + }, + "text-layer": { + "type": "object", + "title": "Text Layer", + "description": "Layer with some text", + "caniuse": "layer-text", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 5 + }, + "t": { + "title": "Data", + "$ref": "#/$defs/text/text-data" + } + }, + "required": [ + "ty", + "t" + ] + } + ] + }, + "data-layer": { + "type": "object", + "title": "Data Layer", + "allOf": [ + { + "$ref": "#/$defs/layers/layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 15 + }, + "refId": { + "title": "Data source Id", + "description": "ID of the data source in assets", + "type": "string" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "precomposition-layer": { + "type": "object", + "title": "Precomposition Layer", + "description": "Layer that renders a Precomposition asset", + "caniuse": "layer-precomp", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 0 + }, + "refId": { + "title": "Reference Id", + "description": "ID of the precomp as specified in the assets", + "type": "string" + }, + "w": { + "title": "Width", + "description": "Width of the clipping rect", + "type": "integer" + }, + "h": { + "title": "Height", + "description": "Height of the clipping rect", + "type": "integer" + }, + "tm": { + "title": "Time Remapping", + "caniuse": "property-timeremap", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", + "refId", + "w", + "h" + ] + } + ] + }, + "shape-layer": { + "type": "object", + "title": "Shape Layer", + "description": "Layer containing Shapes", + "caniuse": "layer-shape", + "allOf": [ + { + "$ref": "#/$defs/layers/visual-layer" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer type", + "type": "integer", + "const": 4 + }, + "shapes": { + "title": "Shapes", + "$ref": "#/$defs/shapes/shape-list" + } + }, + "required": [ + "ty", + "shapes" + ] + } + ] + }, + "layer": { + "type": "object", + "title": "Layer", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ddd": { + "title": "Threedimensional", + "description": "Whether the layer is threedimensional", + "$ref": "#/$defs/helpers/int-boolean", + "default": 0 + }, + "hd": { + "title": "Hidden", + "description": "Whether the layer is hidden", + "type": "boolean" + }, + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "oneOf": [ + { + "const": 0, + "title": "Precomposition layer" + }, + { + "const": 1, + "title": "Solid color layer" + }, + { + "const": 2, + "title": "Image layer" + }, + { + "const": 3, + "title": "Null layer" + }, + { + "const": 4, + "title": "Shape layer" + }, + { + "const": 5, + "title": "Text layer" + }, + { + "const": 6, + "title": "Audio layer" + }, + { + "const": 7, + "title": "Video placeholder" + }, + { + "const": 8, + "title": "Image sequence" + }, + { + "const": 9, + "title": "Video layer" + }, + { + "const": 10, + "title": "Image placeholder" + }, + { + "const": 11, + "title": "Guide layer" + }, + { + "const": 12, + "title": "Adjustment layer" + }, + { + "const": 13, + "title": "Camera" + }, + { + "const": 14, + "title": "Light layer" + }, + { + "const": 15, + "title": "Data layer" + } + ] + }, + "ind": { + "title": "Index", + "type": "integer", + "description": "Index that can be used for parenting and referenced in expressions" + }, + "parent": { + "title": "Parent Index", + "description": "Must be the `ind` property of another layer", + "type": "integer" + }, + "sr": { + "title": "Time Stretch", + "caniuse": "property-time-stretch", + "type": "number", + "default": 1 + }, + "ip": { + "title": "In Point", + "description": "Frame when the layer becomes visible", + "type": "number" + }, + "op": { + "title": "Out Point", + "description": "Frame when the layer becomes invisible", + "type": "number" + }, + "st": { + "title": "Start Time", + "type": "number", + "default": 0 + } + }, + "required": [ + "ty", + "st", + "ip", + "op" + ] + } + ] + } + }, + "shapes": { + "shape-list": { + "title": "Shape List", + "description": "List of valid shapes", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/$defs/shapes/ellipse" + }, + { + "$ref": "#/$defs/shapes/fill" + }, + { + "$ref": "#/$defs/shapes/gradient-fill" + }, + { + "$ref": "#/$defs/shapes/gradient-stroke" + }, + { + "$ref": "#/$defs/shapes/group" + }, + { + "$ref": "#/$defs/shapes/path" + }, + { + "$ref": "#/$defs/shapes/polystar" + }, + { + "$ref": "#/$defs/shapes/pucker-bloat" + }, + { + "$ref": "#/$defs/shapes/rectangle" + }, + { + "$ref": "#/$defs/shapes/repeater" + }, + { + "$ref": "#/$defs/shapes/rounded-corners" + }, + { + "$ref": "#/$defs/shapes/stroke" + }, + { + "$ref": "#/$defs/shapes/transform" + }, + { + "$ref": "#/$defs/shapes/trim" + }, + { + "$ref": "#/$defs/shapes/twist" + }, + { + "$ref": "#/$defs/shapes/merge" + }, + { + "$ref": "#/$defs/shapes/offset-path" + }, + { + "$ref": "#/$defs/shapes/zig-zag" + }, + { + "$ref": "#/$defs/shapes/no-style" + } + ] + } + }, + "rectangle": { + "type": "object", + "title": "Rectangle", + "description": "A simple rectangle shape", + "caniuse": "shape-rectangle", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "rc" + }, + "p": { + "title": "Position", + "description": "Center of the rectangle", + "$ref": "#/$defs/animated-properties/position" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "r": { + "title": "Rounded", + "description": "Rounded corners radius", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", + "s", + "p", + "r" + ] + } + ] + }, + "twist": { + "type": "object", + "title": "Twist", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "tw" + }, + "a": { + "title": "Angle", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Center", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "rounded-corners": { + "type": "object", + "title": "Rounded Corners", + "description": "Rounds corners of other shapes", + "allOf": [ + { + "$ref": "#/$defs/shapes/modifier" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "rd" + }, + "r": { + "title": "Radius", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", + "r" + ] + } + ] + }, + "polystar": { + "type": "object", + "title": "PolyStar", + "description": "Star or regular polygon", + "caniuse": "shape-polystar", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "sr" + }, + "p": { + "title": "Position", + "$ref": "#/$defs/animated-properties/position" + }, + "or": { + "title": "Outer Radius", + "$ref": "#/$defs/animated-properties/value" + }, + "os": { + "title": "Outer Roundness", + "description": "Outer Roundness as a percentage", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Rotation", + "description": "Rotation, clockwise in degrees", + "$ref": "#/$defs/animated-properties/value" + }, + "pt": { + "title": "Points", + "$ref": "#/$defs/animated-properties/value" + }, + "sy": { + "title": "Star Type", + "description": "Star type, `1` for Star, `2` for Polygon", + "$ref": "#/$defs/constants/star-type", + "default": 1 + } + }, + "required": [ + "ty", + "or", + "os", + "pt", + "p", + "r" + ] + }, + { + "if": { + "properties": { + "sy": { + "const": 1 + } + } + }, + "then": { + "properties": { + "ir": { + "title": "Inner Radius", + "$ref": "#/$defs/animated-properties/value" + }, + "is": { + "title": "Inner Roundness", + "description": "Inner Roundness as a percentage", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ir", + "is" + ] + } + } + ] + }, + "shape-element": { + "type": "object", + "title": "Shape Element", + "description": "Base class for all elements of ShapeLayer and Group", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "hd": { + "title": "Hidden", + "description": "Whether the shape is hidden", + "type": "boolean" + }, + "ty": { + "title": "Shape Type", + "type": "string", + "oneOf": [ + { + "const": "rc", + "title": "Rectangle" + }, + { + "const": "el", + "title": "Ellipse" + }, + { + "const": "sr", + "title": "Polygon / Star" + }, + { + "const": "sh", + "title": "Path" + }, + { + "const": "fl", + "title": "Fill" + }, + { + "const": "st", + "title": "Stroke" + }, + { + "const": "gf", + "title": "Gradient fill" + }, + { + "const": "gs", + "title": "Gradient stroke" + }, + { + "const": "no", + "title": "No Style" + }, + { + "const": "gr", + "title": "Group" + }, + { + "const": "tr", + "title": "Transform" + }, + { + "const": "rd", + "title": "Rounded corners" + }, + { + "const": "pb", + "title": "Pucker / bloat" + }, + { + "const": "mm", + "title": "Merge" + }, + { + "const": "tw", + "title": "Twist" + }, + { + "const": "op", + "title": "Offset path" + }, + { + "const": "zz", + "title": "Zig zag" + }, + { + "const": "rp", + "title": "Repeater" + }, + { + "const": "tm", + "title": "Trim" + } + ] + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/constants/blend-mode" + }, + "ix": { + "title": "Property index", + "description": "Index used in expressions", + "type": "integer" + }, + "cl": { + "title": "CSS Class", + "description": "CSS class used by the SVG renderer", + "type": "string" + }, + "ln": { + "title": "Layer XML ID", + "description": "`id` attribute used by the SVG renderer", + "type": "string" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "ellipse": { + "type": "object", + "title": "Ellipse", + "description": "Ellipse shape", + "caniuse": "shape-ellipse", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "el" + }, + "p": { + "title": "Position", + "$ref": "#/$defs/animated-properties/position" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "ty", + "s", + "p" + ] + } + ] + }, + "modifier": { + "type": "object", + "title": "Modifier", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + } + ] + }, + "trim": { + "type": "object", + "title": "Trim", + "description": "Trims shapes into a segment", + "caniuse": "shape-trim-path", + "allOf": [ + { + "$ref": "#/$defs/shapes/modifier" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "tm" + }, + "s": { + "title": "Start", + "description": "Segment start", + "$ref": "#/$defs/animated-properties/value" + }, + "e": { + "title": "End", + "description": "Segment end", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + }, + "m": { + "title": "Multiple", + "description": "How to treat multiple copies", + "$ref": "#/$defs/constants/trim-multiple-shapes" + } + }, + "required": [ + "ty", + "o", + "s", + "e" + ] + } + ] + }, + "transform": { + "type": "object", + "title": "Transform Shape", + "description": "Group transform", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/helpers/transform" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "tr" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "offset-path": { + "type": "object", + "title": "Offset Path", + "caniuse": "shape-offset-path", + "description": "Interpolates the shape with its center point and bezier tangents with the opposite direction", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "op" + }, + "a": { + "title": "Amount", + "$ref": "#/$defs/animated-properties/value" + }, + "lj": { + "title": "Line Join", + "$ref": "#/$defs/constants/line-join", + "default": 2 + }, + "ml": { + "title": "Miter Limit", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "no-style": { + "type": "object", + "title": "No Style", + "description": "Represents a style for shapes without fill or stroke", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "no" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "gradient": { + "type": "object", + "title": "Gradient", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "s": { + "title": "Start Point", + "description": "Starting point for the gradient", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "e": { + "title": "End Point", + "description": "End point for the gradient", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "t": { + "title": "Gradient Type", + "description": "Type of the gradient", + "$ref": "#/$defs/constants/gradient-type", + "default": 1 + }, + "h": { + "title": "Highlight Length", + "description": "Highlight Length, as a percentage between `s` and `e`", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Highlight Angle", + "description": "Highlight Angle, relative to the direction from `s` to `e`", + "$ref": "#/$defs/animated-properties/value" + }, + "g": { + "title": "Colors", + "description": "Gradient colors", + "$ref": "#/$defs/animated-properties/gradient-colors" + } + }, + "required": [ + "s", + "e", + "g" + ] + } + ] + }, + "base-stroke": { + "type": "object", + "title": "Base Stroke", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "lc": { + "title": "Line Cap", + "$ref": "#/$defs/constants/line-cap", + "default": 2 + }, + "lj": { + "title": "Line Join", + "$ref": "#/$defs/constants/line-join", + "default": 2 + }, + "ml": { + "title": "Miter Limit", + "type": "number", + "default": 0 + }, + "ml2": { + "title": "Miter Limit", + "description": "Animatable alternative to ml", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Opacity", + "description": "Opacity, 100 means fully opaque", + "$ref": "#/$defs/animated-properties/value" + }, + "w": { + "title": "Width", + "description": "Stroke width", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Dashes", + "description": "Dashed line definition", + "type": "array", + "items": { + "$ref": "#/$defs/shapes/stroke-dash" + } + } + }, + "required": [ + "o", + "w" + ] + } + ] + }, + "group": { + "type": "object", + "title": "Group", + "description": "Shape Element that can contain other shapes", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "gr" + }, + "np": { + "title": "Number Of Properties", + "type": "number" + }, + "it": { + "title": "Shapes", + "$ref": "#/$defs/shapes/shape-list" + }, + "cix": { + "title": "Property index", + "description": "Index used in expressions", + "type": "integer" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "gradient-fill": { + "type": "object", + "title": "Gradient Fill", + "description": "Gradient fill", + "caniuse": "shape-fill-gradient", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/shapes/gradient" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "gf" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Fill Rule", + "$ref": "#/$defs/constants/fill-rule" + } + }, + "required": [ + "ty", + "o" + ] + } + ] + }, + "fill": { + "type": "object", + "title": "Fill", + "description": "Solid fill color", + "caniuse": "shape-fill", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "fl" + }, + "o": { + "title": "Opacity", + "description": "Opacity, 100 means fully opaque", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "r": { + "title": "Fill Rule", + "$ref": "#/$defs/constants/fill-rule" + } + }, + "required": [ + "ty", + "c", + "o" + ] + } + ] + }, + "shape": { + "type": "object", + "title": "Shape", + "description": "Drawable shape", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "d": { + "title": "Direction", + "description": "Direction the shape is drawn as, mostly relevant when using trim path", + "$ref": "#/$defs/constants/shape-direction" + } + } + } + ] + }, + "repeater": { + "type": "object", + "title": "Repeater", + "description": "Duplicates previous shapes in a group", + "caniuse": "shape-repeater", + "allOf": [ + { + "$ref": "#/$defs/shapes/modifier" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "rp" + }, + "c": { + "title": "Copies", + "description": "Number of copies", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + }, + "m": { + "title": "Composite", + "description": "Stacking order", + "$ref": "#/$defs/constants/composite", + "default": 1 + }, + "tr": { + "title": "Transform", + "description": "Transform applied to each copy", + "$ref": "#/$defs/shapes/repeater-transform" + } + }, + "required": [ + "ty", + "c", + "tr" + ] + } + ] + }, + "path": { + "type": "object", + "title": "Path", + "description": "Animatable Bezier curve", + "caniuse": "shape-path", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "sh" + }, + "ks": { + "title": "Shape", + "description": "Bezier path", + "$ref": "#/$defs/animated-properties/shape-property" + } + }, + "required": [ + "ty", + "ks" + ] + } + ] + }, + "stroke": { + "type": "object", + "title": "Stroke", + "description": "Solid stroke", + "caniuse": "shape-stroke", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/shapes/base-stroke" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "st" + }, + "c": { + "title": "Color", + "description": "Stroke color", + "$ref": "#/$defs/animated-properties/color-value" + } + }, + "required": [ + "ty", + "c" + ] + } + ] + }, + "gradient-stroke": { + "type": "object", + "title": "Gradient Stroke", + "description": "Gradient stroke", + "caniuse": "shape-stroke-gradient", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/shapes/base-stroke" + }, + { + "$ref": "#/$defs/shapes/gradient" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "gs" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "pucker-bloat": { + "type": "object", + "title": "Pucker Bloat", + "description": "Interpolates the shape with its center point and bezier tangents with the opposite direction", + "caniuse": "shape-pucker-and-bloat", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "pb" + }, + "a": { + "title": "Amount", + "description": "Amount as a percentage", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "repeater-transform": { + "type": "object", + "title": "Repeater Transform", + "description": "Transform used by a repeater, the transform is applied to each subsequent repeated object.", + "allOf": [ + { + "$ref": "#/$defs/helpers/transform" + }, + { + "type": "object", + "properties": { + "so": { + "title": "Start Opacity", + "description": "Opacity of the first repeated object.", + "$ref": "#/$defs/animated-properties/value" + }, + "eo": { + "title": "End Opacity", + "description": "Opacity of the last repeated object.", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] + }, + "zig-zag": { + "type": "object", + "title": "Zig Zag", + "description": "Changes the edges of affected shapes into a series of peaks and valleys of uniform size", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "zz" + }, + "r": { + "title": "Frequency", + "description": "Number of ridges per segment", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Amplitude", + "description": "Distance between peaks and troughs", + "$ref": "#/$defs/animated-properties/value" + }, + "pt": { + "title": "Point Type", + "description": "Point type (1 = corner, 2 = smooth)", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "merge": { + "type": "object", + "title": "Merge", + "caniuse": "shape-merge-path", + "description": "Boolean operator on shapes", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "mm" + }, + "mm": { + "title": "Merge Mode", + "$ref": "#/$defs/constants/merge-mode", + "default": 1 + } + }, + "required": [ + "ty" + ] + } + ] + }, + "stroke-dash": { + "type": "object", + "title": "Stroke Dash", + "description": "An item used to described the dashe pattern in a stroked path", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "n": { + "title": "Dash Type", + "$ref": "#/$defs/constants/stroke-dash-type", + "default": "d" + }, + "v": { + "title": "Length", + "description": "Length of the dash", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] + } + }, + "styles": { + "satin-style": { + "type": "object", + "title": "Satin", + "caniuse": "style-satin", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 6 + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Distance", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/value" + }, + "in": { + "title": "Invert", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "gradient-overlay-style": { + "type": "object", + "title": "Gradient Overlay", + "caniuse": "style-gradient-overlay", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 8 + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "gf": { + "title": "Gradient", + "$ref": "#/$defs/animated-properties/gradient-colors" + }, + "gs": { + "title": "Smoothness", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "$ref": "#/$defs/animated-properties/value" + }, + "gt": { + "title": "Gradient Type", + "$ref": "#/$defs/constants/gradient-type" + }, + "re": { + "title": "Reverse", + "$ref": "#/$defs/animated-properties/value" + }, + "al": { + "title": "Align", + "description": "Align with layer", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Scale", + "$ref": "#/$defs/animated-properties/value" + }, + "of": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "color-overlay-style": { + "type": "object", + "title": "Color Overlay", + "caniuse": "style-color-overlay", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 7 + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "so": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "outer-glow-style": { + "type": "object", + "title": "Outer Glow", + "caniuse": "style-outer-glow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 3 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Range", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + }, + "j": { + "title": "Jitter", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "stroke-style": { + "type": "object", + "title": "Layer Stroke", + "caniuse": "style-stroke", + "description": "Stroke / frame", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 0 + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "inner-glow-style": { + "type": "object", + "title": "Inner Glow", + "caniuse": "style-inner-glow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 4 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Range", + "$ref": "#/$defs/animated-properties/value" + }, + "sr": { + "title": "Source", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + }, + "j": { + "title": "Jitter", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "layer-style": { + "type": "object", + "title": "Layer Style", + "description": "Style applied to a layer", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Style Type", + "type": "integer" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "drop-shadow-style": { + "type": "object", + "title": "Drop Shadow", + "caniuse": "style-drop-shadow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 1 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "description": "Local light angle", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "description": "Blur size", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Distance", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + }, + "lc": { + "title": "Layer Conceal", + "description": "Layer knowck out drop shadow", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "inner-shadow-style": { + "type": "object", + "title": "Inner Shadow", + "caniuse": "style-inner-shadow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 2 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "description": "Local light angle", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "description": "Blur size", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Distance", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + }, + "bevel-emboss-style": { + "type": "object", + "title": "Bevel Emboss", + "caniuse": "style-bevel-and-emboss", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 5 + }, + "bs": { + "title": "Bevel Style", + "$ref": "#/$defs/animated-properties/value" + }, + "bt": { + "title": "Technique", + "$ref": "#/$defs/animated-properties/value" + }, + "sr": { + "title": "Strength", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/value" + }, + "sf": { + "title": "Soften", + "$ref": "#/$defs/animated-properties/value" + }, + "ga": { + "title": "Global Angle", + "description": "Use global light", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "description": "Local lighting angle", + "$ref": "#/$defs/animated-properties/value" + }, + "ll": { + "title": "Altitude", + "description": "Local lighting altitude", + "$ref": "#/$defs/animated-properties/value" + }, + "hm": { + "title": "Highlight Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "hc": { + "title": "Highlight Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "ho": { + "title": "Highlight Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "sm": { + "title": "Shadow Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "sc": { + "title": "Shadow Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "so": { + "title": "Shadow Opacity", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] + } + }, + "text": { + "animated-text-document": { + "type": "object", + "title": "Animated Text Document", + "description": "Animated property representing the text contents", + "properties": { + "k": { + "title": "Keyframes", + "type": "array", + "items": { + "$ref": "#/$defs/text/text-document-keyframe" + } + }, + "x": { + "title": "Expression", + "type": "string" + }, + "sid": { + "title": "Slot ID", + "description": "One of the ID in the file's slots", + "type": "string" + } + }, + "required": [ + "k" + ] + }, + "text-document-keyframe": { + "type": "object", + "title": "Text Document Keyframe", + "description": "A keyframe containing a text document", + "properties": { + "s": { + "title": "Start", + "$ref": "#/$defs/text/text-document" + }, + "t": { + "title": "Time", + "type": "number", + "default": 0 + } + }, + "required": [ + "s", + "t" + ] + }, + "text-follow-path": { + "type": "object", + "title": "Text Follow Path", + "caniuse": "text-path", + "description": "Uses the path described by a layer mask to put the text on said path.", + "allOf": [ + { + "type": "object", + "properties": { + "m": { + "title": "Mask", + "type": "integer", + "description": "Index of the mask to use" + }, + "f": { + "title": "First Margin", + "$ref": "#/$defs/animated-properties/value" + }, + "l": { + "title": "Last Margin", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Reverse Path", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Force Alignment", + "$ref": "#/$defs/animated-properties/value" + }, + "p": { + "title": "Perpendicular To Path", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] + }, + "font-list": { + "type": "object", + "title": "Font List", + "description": "List of fonts", + "allOf": [ + { + "type": "object", + "properties": { + "list": { + "title": "List", + "type": "array", + "items": { + "$ref": "#/$defs/text/font" + } + } + }, + "required": [] + } + ] + }, + "character-precomp": { + "type": "object", + "title": "Character Precomp", + "description": "Defines a character as a precomp layer", + "properties": { + "refId": { + "title": "Reference Id", + "description": "ID of the precomp as specified in the assets", + "type": "string" + }, + "ks": { + "title": "Transform", + "description": "Layer transform", + "$ref": "#/$defs/helpers/transform" + }, + "ip": { + "title": "In Point", + "description": "Frame when the layer becomes visible", + "type": "number", + "default": 0 + }, + "op": { + "title": "Out Point", + "description": "Frame when the layer becomes invisible", + "type": "number", + "default": 99999 + }, + "sr": { + "title": "Time Stretch", + "type": "number", + "default": 1 + }, + "st": { + "title": "Start Time", + "type": "number", + "default": 0 + } + }, + "required": [ + "refId" + ] + }, + "character-data": { + "type": "object", + "title": "Character Data", + "description": "Defines character shapes", + "properties": { + "ch": { + "title": "Character", + "type": "string", + "default": "" + }, + "fFamily": { + "title": "Font Family", + "type": "string", + "default": "" + }, + "size": { + "title": "Font Size", + "type": "number", + "default": 0 + }, + "style": { + "title": "Font Style", + "type": "string", + "default": "" + }, + "w": { + "title": "Width", + "type": "number", + "default": 0 + }, + "data": { + "title": "Data", + "oneOf": [ + { + "$ref": "#/$defs/text/character-shapes" + }, + { + "$ref": "#/$defs/text/character-precomp" + } + ] + } + }, + "required": [ + "data", + "ch", + "fFamily", + "size", + "style", + "w" + ] + }, + "font": { + "type": "object", + "title": "Font", + "description": "Describes how a font with given settings should be loaded", + "allOf": [ + { + "type": "object", + "properties": { + "ascent": { + "title": "Ascent", + "type": "number", + "description": "Text will be moved down based on this value" + }, + "fFamily": { + "title": "Font Family", + "type": "string", + "default": "sans" + }, + "fName": { + "title": "Name", + "description": "Name used by text documents to reference this font, usually it's `fFamily` followed by `fStyle`", + "type": "string", + "default": "sans-Regular" + }, + "fStyle": { + "title": "Font Style", + "examples": [ + "Regular", + "Bold", + "Bold Italic" + ], + "type": "string", + "default": "Regular" + }, + "fPath": { + "title": "Path", + "type": "string" + }, + "fWeight": { + "title": "Weight", + "type": "string" + }, + "origin": { + "title": "Origin", + "$ref": "#/$defs/constants/font-path-origin" + }, + "fClass": { + "type": "string", + "title": "CSS Class", + "description": "CSS Class applied to text objects using this font" + } + }, + "required": [ + "fFamily", + "fName", + "fStyle" + ] + } + ] + }, + "text-data": { + "type": "object", + "title": "Text Data", + "description": "Contains all the text data and animation", + "allOf": [ + { + "type": "object", + "properties": { + "a": { + "title": "Ranges", + "caniuse": "text-animators", + "type": "array", + "items": { + "$ref": "#/$defs/text/text-range" + } + }, + "d": { + "title": "Document", + "$ref": "#/$defs/text/animated-text-document" + }, + "m": { + "title": "Alignment", + "$ref": "#/$defs/text/text-alignment-options" + }, + "p": { + "title": "Follow Path", + "$ref": "#/$defs/text/text-follow-path" + } + }, + "required": [ + "a", + "d", + "m", + "p" + ] + } + ] + }, + "text-range-selector": { + "type": "object", + "title": "Text Range Selector", + "caniuse": "animators-range-selectors", + "properties": { + "t": { + "title": "Expressible", + "$ref": "#/$defs/helpers/int-boolean" + }, + "xe": { + "title": "Max Ease", + "$ref": "#/$defs/animated-properties/value" + }, + "ne": { + "title": "Min Ease", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Max Amount", + "$ref": "#/$defs/animated-properties/value" + }, + "b": { + "title": "Based On", + "$ref": "#/$defs/constants/text-based" + }, + "rn": { + "title": "Randomize", + "$ref": "#/$defs/helpers/int-boolean" + }, + "sh": { + "title": "Shape", + "$ref": "#/$defs/constants/text-shape" + }, + "o": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Range Units", + "caniuse": "range-selectors-units", + "$ref": "#/$defs/constants/text-range-units" + }, + "sm": { + "title": "Selector Smoothness", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Start", + "$ref": "#/$defs/animated-properties/value" + }, + "e": { + "title": "End", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "t", + "a", + "b", + "sh" + ] + }, + "text-alignment-options": { + "type": "object", + "title": "Text Alignment Options", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "a": { + "title": "Alignment", + "description": "Group alignment", + "caniuse": "animators-grouping-alignment", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "g": { + "title": "Grouping", + "description": "Anchor point grouping", + "caniuse": "animators-anchor-point-grouping", + "$ref": "#/$defs/constants/text-grouping" + } + }, + "required": [] + } + ] + }, + "text-style": { + "type": "object", + "title": "Text Style", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/helpers/transform" + }, + { + "type": "object", + "properties": { + "sw": { + "title": "Stroke Width", + "$ref": "#/$defs/animated-properties/value" + }, + "sc": { + "title": "Stroke Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "sh": { + "title": "Stroke Hue", + "$ref": "#/$defs/animated-properties/value" + }, + "ss": { + "title": "Stroke Saturation", + "$ref": "#/$defs/animated-properties/value" + }, + "sb": { + "title": "Stroke Brightness", + "$ref": "#/$defs/animated-properties/value" + }, + "so": { + "title": "Stroke Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "fc": { + "title": "Fill Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "fh": { + "title": "Fill Hue", + "$ref": "#/$defs/animated-properties/value" + }, + "fs": { + "title": "Fill Saturation", + "$ref": "#/$defs/animated-properties/value" + }, + "fb": { + "title": "Fill Brightness", + "$ref": "#/$defs/animated-properties/value" + }, + "fo": { + "title": "Fill Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "t": { + "title": "Letter Spacing", + "$ref": "#/$defs/animated-properties/value" + }, + "bl": { + "title": "Blur", + "caniuse": "text-animators-blur", + "$ref": "#/$defs/animated-properties/value" + }, + "ls": { + "title": "Line Spacing", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] + }, + "text-range": { + "type": "object", + "title": "Text Range", + "description": "Range of text with custom animations and style", + "caniuse": "animators-range-selectors", + "properties": { + "nm": { + "title": "Name", + "type": "string" + }, + "s": { + "title": "Selector", + "$ref": "#/$defs/text/text-range-selector" + }, + "a": { + "title": "Style", + "$ref": "#/$defs/text/text-style" + } + } + }, + "character-shapes": { + "type": "object", + "title": "Character Shape", + "description": "Defines a character as shapes", + "properties": { + "shapes": { + "title": "Shapes", + "description": "Shapes forming the character", + "$ref": "#/$defs/shapes/shape-list" + } + }, + "required": [ + "shapes" + ] + }, + "text-document": { + "type": "object", + "title": "Text Document", + "description": "", + "properties": { + "f": { + "title": "Font Family", + "type": "string", + "default": "" + }, + "fc": { + "title": "Fill Color", + "$ref": "#/$defs/helpers/color", + "default": [ + 0, + 0, + 0 + ] + }, + "sc": { + "title": "Stroke Color", + "$ref": "#/$defs/helpers/color" + }, + "sw": { + "title": "Stroke Width", + "type": "number", + "default": 0 + }, + "of": { + "title": "Stroke Over Fill", + "description": "Render stroke above the fill", + "type": "boolean" + }, + "s": { + "title": "Font Size", + "type": "number", + "default": 10 + }, + "lh": { + "title": "Line Height", + "description": "Distance between lines on multiline or wrapped text", + "type": "number" + }, + "sz": { + "title": "Wrap Size", + "description": "Size of the box containing the text", + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "number" + } + }, + "ps": { + "title": "Wrap Position", + "description": "Position of the box containing the text", + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "number" + } + }, + "t": { + "title": "Text", + "type": "string", + "description": "Text, note that newlines are encoded with \\r", + "default": "" + }, + "j": { + "title": "Justify", + "$ref": "#/$defs/constants/text-justify", + "default": 0 + }, + "ca": { + "title": "Text Caps", + "$ref": "#/$defs/constants/text-caps" + }, + "tr": { + "title": "Tracking", + "description": "Text Tracking", + "type": "number" + }, + "ls": { + "title": "Baseline Shift", + "type": "number" + } + }, + "required": [ + "f", + "fc", + "s", + "t" + ] + } + } + } +} \ No newline at end of file diff --git a/schema/shapes/base-stroke.json b/schema/shapes/base-stroke.json new file mode 100644 index 00000000..0f1c229a --- /dev/null +++ b/schema/shapes/base-stroke.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Base Stroke", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "lc": { + "title": "Line Cap", + "$ref": "#/$defs/constants/line-cap", + "default": 2 + }, + "lj": { + "title": "Line Join", + "$ref": "#/$defs/constants/line-join", + "default": 2 + }, + "ml": { + "title": "Miter Limit", + "type": "number", + "default": 0 + }, + "ml2": { + "title": "Miter Limit", + "description": "Animatable alternative to ml", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Opacity", + "description": "Opacity, 100 means fully opaque", + "$ref": "#/$defs/animated-properties/value" + }, + "w": { + "title": "Width", + "description": "Stroke width", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Dashes", + "description": "Dashed line definition", + "type": "array", + "items": { + "$ref": "#/$defs/shapes/stroke-dash" + } + } + }, + "required": ["o", "w"] + } + ] +} diff --git a/schema/shapes/ellipse.json b/schema/shapes/ellipse.json new file mode 100644 index 00000000..007ec952 --- /dev/null +++ b/schema/shapes/ellipse.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Ellipse", + "description": "Ellipse shape", + "caniuse": "shape-ellipse", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "el" + }, + "p": { + "title": "Position", + "$ref": "#/$defs/animated-properties/position" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "ty", "s", "p" + ] + } + ] +} diff --git a/schema/shapes/fill.json b/schema/shapes/fill.json new file mode 100644 index 00000000..31fc0396 --- /dev/null +++ b/schema/shapes/fill.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Fill", + "description": "Solid fill color", + "caniuse": "shape-fill", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "fl" + }, + "o": { + "title": "Opacity", + "description": "Opacity, 100 means fully opaque", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "r": { + "title": "Fill Rule", + "$ref": "#/$defs/constants/fill-rule" + } + }, + "required": [ + "ty", "c", "o" + ] + } + ] +} diff --git a/schema/shapes/gradient-fill.json b/schema/shapes/gradient-fill.json new file mode 100644 index 00000000..59c7fd4e --- /dev/null +++ b/schema/shapes/gradient-fill.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Gradient Fill", + "description": "Gradient fill", + "caniuse": "shape-fill-gradient", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/shapes/gradient" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "gf" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Fill Rule", + "$ref": "#/$defs/constants/fill-rule" + } + }, + "required": [ + "ty", "o" + ] + } + ] +} diff --git a/schema/shapes/gradient-stroke.json b/schema/shapes/gradient-stroke.json new file mode 100644 index 00000000..13897d00 --- /dev/null +++ b/schema/shapes/gradient-stroke.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Gradient Stroke", + "description": "Gradient stroke", + "caniuse": "shape-stroke-gradient", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/shapes/base-stroke" + }, + { + "$ref": "#/$defs/shapes/gradient" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "gs" + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/shapes/gradient.json b/schema/shapes/gradient.json new file mode 100644 index 00000000..a21b21dc --- /dev/null +++ b/schema/shapes/gradient.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Gradient", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "s": { + "title": "Start Point", + "description": "Starting point for the gradient", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "e": { + "title": "End Point", + "description": "End point for the gradient", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "t": { + "title": "Gradient Type", + "description": "Type of the gradient", + "$ref": "#/$defs/constants/gradient-type", + "default": 1 + }, + "h": { + "title": "Highlight Length", + "description": "Highlight Length, as a percentage between `s` and `e`", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Highlight Angle", + "description": "Highlight Angle, relative to the direction from `s` to `e`", + "$ref": "#/$defs/animated-properties/value" + }, + "g": { + "title": "Colors", + "description": "Gradient colors", + "$ref": "#/$defs/animated-properties/gradient-colors" + } + }, + "required": [ + "s", "e", "g" + ] + } + ] +} diff --git a/schema/shapes/group.json b/schema/shapes/group.json new file mode 100644 index 00000000..dbf98d41 --- /dev/null +++ b/schema/shapes/group.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Group", + "description": "Shape Element that can contain other shapes", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "gr" + }, + "np": { + "title": "Number Of Properties", + "type": "number" + }, + "it": { + "title": "Shapes", + "$ref": "#/$defs/shapes/shape-list" + }, + "cix": { + "title": "Property index", + "description": "Index used in expressions", + "type": "integer" + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/shapes/merge.json b/schema/shapes/merge.json new file mode 100644 index 00000000..aa8b54e5 --- /dev/null +++ b/schema/shapes/merge.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Merge", + "caniuse": "shape-merge-path", + "description": "Boolean operator on shapes", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "mm" + }, + "mm": { + "title": "Merge Mode", + "$ref": "#/$defs/constants/merge-mode", + "default": 1 + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/shapes/modifier.json b/schema/shapes/modifier.json new file mode 100644 index 00000000..9f7953b7 --- /dev/null +++ b/schema/shapes/modifier.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Modifier", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + } + ] +} diff --git a/schema/shapes/no-style.json b/schema/shapes/no-style.json new file mode 100644 index 00000000..01320503 --- /dev/null +++ b/schema/shapes/no-style.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "No Style", + "description": "Represents a style for shapes without fill or stroke", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "no" + } + }, + "required": [ + "ty" + ] + } + ] +} + diff --git a/schema/shapes/offset-path.json b/schema/shapes/offset-path.json new file mode 100644 index 00000000..90883df8 --- /dev/null +++ b/schema/shapes/offset-path.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Offset Path", + "caniuse": "shape-offset-path", + "description": "Interpolates the shape with its center point and bezier tangents with the opposite direction", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "op" + }, + "a": { + "title": "Amount", + "$ref": "#/$defs/animated-properties/value" + }, + "lj": { + "title": "Line Join", + "$ref": "#/$defs/constants/line-join", + "default": 2 + }, + "ml": { + "title": "Miter Limit", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/shapes/path.json b/schema/shapes/path.json new file mode 100644 index 00000000..b93349c9 --- /dev/null +++ b/schema/shapes/path.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Path", + "description": "Animatable Bezier curve", + "caniuse": "shape-path", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "sh" + }, + "ks": { + "title": "Shape", + "description": "Bezier path", + "$ref": "#/$defs/animated-properties/shape-property" + } + }, + "required": [ + "ty", "ks" + ] + } + ] +} diff --git a/schema/shapes/polystar.json b/schema/shapes/polystar.json new file mode 100644 index 00000000..f1416b78 --- /dev/null +++ b/schema/shapes/polystar.json @@ -0,0 +1,76 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "PolyStar", + "description": "Star or regular polygon", + "caniuse": "shape-polystar", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "sr" + }, + "p": { + "title": "Position", + "$ref": "#/$defs/animated-properties/position" + }, + "or": { + "title": "Outer Radius", + "$ref": "#/$defs/animated-properties/value" + }, + "os": { + "title": "Outer Roundness", + "description": "Outer Roundness as a percentage", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Rotation", + "description": "Rotation, clockwise in degrees", + "$ref": "#/$defs/animated-properties/value" + }, + "pt": { + "title": "Points", + "$ref": "#/$defs/animated-properties/value" + }, + "sy": { + "title": "Star Type", + "description": "Star type, `1` for Star, `2` for Polygon", + "$ref": "#/$defs/constants/star-type", + "default": 1 + } + }, + "required": [ + "ty", "or", "os", "pt", "p", "r" + ] + }, + { + "if": { + "properties": { + "sy": { + "const": 1 + } + } + }, + "then": { + "properties": { + "ir": { + "title": "Inner Radius", + "$ref": "#/$defs/animated-properties/value" + }, + "is": { + "title": "Inner Roundness", + "description": "Inner Roundness as a percentage", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ir", "is"] + } + } + ] +} diff --git a/schema/shapes/pucker-bloat.json b/schema/shapes/pucker-bloat.json new file mode 100644 index 00000000..6b98d70e --- /dev/null +++ b/schema/shapes/pucker-bloat.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Pucker Bloat", + "description": "Interpolates the shape with its center point and bezier tangents with the opposite direction", + "caniuse": "shape-pucker-and-bloat", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "pb" + }, + "a": { + "title": "Amount", + "description": "Amount as a percentage", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} diff --git a/schema/shapes/rectangle.json b/schema/shapes/rectangle.json new file mode 100644 index 00000000..0f1b26bb --- /dev/null +++ b/schema/shapes/rectangle.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Rectangle", + "description": "A simple rectangle shape", + "caniuse": "shape-rectangle", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "rc" + }, + "p": { + "title": "Position", + "description": "Center of the rectangle", + "$ref": "#/$defs/animated-properties/position" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "r": { + "title": "Rounded", + "description": "Rounded corners radius", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", "s", "p", "r" + ] + } + ] +} diff --git a/schema/shapes/repeater-transform.json b/schema/shapes/repeater-transform.json new file mode 100644 index 00000000..e8935ad3 --- /dev/null +++ b/schema/shapes/repeater-transform.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Repeater Transform", + "description": "Transform used by a repeater, the transform is applied to each subsequent repeated object.", + "allOf": [ + { + "$ref": "#/$defs/helpers/transform" + }, + { + "type": "object", + "properties": { + "so": { + "title": "Start Opacity", + "description": "Opacity of the first repeated object.", + "$ref": "#/$defs/animated-properties/value" + }, + "eo": { + "title": "End Opacity", + "description": "Opacity of the last repeated object.", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] +} diff --git a/schema/shapes/repeater.json b/schema/shapes/repeater.json new file mode 100644 index 00000000..97cff870 --- /dev/null +++ b/schema/shapes/repeater.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Repeater", + "description": "Duplicates previous shapes in a group", + "caniuse": "shape-repeater", + "allOf": [ + { + "$ref": "#/$defs/shapes/modifier" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "rp" + }, + "c": { + "title": "Copies", + "description": "Number of copies", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + }, + "m": { + "title": "Composite", + "description": "Stacking order", + "$ref": "#/$defs/constants/composite", + "default": 1 + }, + "tr": { + "title": "Transform", + "description": "Transform applied to each copy", + "$ref": "#/$defs/shapes/repeater-transform" + } + }, + "required": [ + "ty", "c", "tr" + ] + } + ] +} diff --git a/schema/shapes/rounded-corners.json b/schema/shapes/rounded-corners.json new file mode 100644 index 00000000..fdc0cdb2 --- /dev/null +++ b/schema/shapes/rounded-corners.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Rounded Corners", + "description": "Rounds corners of other shapes", + "allOf": [ + { + "$ref": "#/$defs/shapes/modifier" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "rd" + }, + "r": { + "title": "Radius", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty", "r" + ] + } + ] +} diff --git a/schema/shapes/shape-element.json b/schema/shapes/shape-element.json new file mode 100644 index 00000000..7d37f357 --- /dev/null +++ b/schema/shapes/shape-element.json @@ -0,0 +1,123 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Shape Element", + "description": "Base class for all elements of ShapeLayer and Group", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "hd": { + "title": "Hidden", + "description": "Whether the shape is hidden", + "type": "boolean" + }, + "ty": { + "title": "Shape Type", + "type": "string", + "oneOf": [ + { + "const": "rc", + "title": "Rectangle" + }, + { + "const": "el", + "title": "Ellipse" + }, + { + "const": "sr", + "title": "Polygon / Star" + }, + { + "const": "sh", + "title": "Path" + }, + { + "const": "fl", + "title": "Fill" + }, + { + "const": "st", + "title": "Stroke" + }, + { + "const": "gf", + "title": "Gradient fill" + }, + { + "const": "gs", + "title": "Gradient stroke" + }, + { + "const": "no", + "title": "No Style" + }, + { + "const": "gr", + "title": "Group" + }, + { + "const": "tr", + "title": "Transform" + }, + { + "const": "rd", + "title": "Rounded corners" + }, + { + "const": "pb", + "title": "Pucker / bloat" + }, + { + "const": "mm", + "title": "Merge" + }, + { + "const": "tw", + "title": "Twist" + }, + { + "const": "op", + "title": "Offset path" + }, + { + "const": "zz", + "title": "Zig zag" + }, + { + "const": "rp", + "title": "Repeater" + }, + { + "const": "tm", + "title": "Trim" + } + ] + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/constants/blend-mode" + }, + "ix": { + "title": "Property index", + "description": "Index used in expressions", + "type": "integer" + }, + "cl": { + "title": "CSS Class", + "description": "CSS class used by the SVG renderer", + "type": "string" + }, + "ln": { + "title": "Layer XML ID", + "description": "`id` attribute used by the SVG renderer", + "type": "string" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/shapes/shape-list.json b/schema/shapes/shape-list.json new file mode 100644 index 00000000..7308b1e9 --- /dev/null +++ b/schema/shapes/shape-list.json @@ -0,0 +1,28 @@ +{ + "title": "Shape List", + "description": "List of valid shapes", + "type": "array", + "items": { + "oneOf": [ + {"$ref": "#/$defs/shapes/ellipse"}, + {"$ref": "#/$defs/shapes/fill"}, + {"$ref": "#/$defs/shapes/gradient-fill"}, + {"$ref": "#/$defs/shapes/gradient-stroke"}, + {"$ref": "#/$defs/shapes/group"}, + {"$ref": "#/$defs/shapes/path"}, + {"$ref": "#/$defs/shapes/polystar"}, + {"$ref": "#/$defs/shapes/pucker-bloat"}, + {"$ref": "#/$defs/shapes/rectangle"}, + {"$ref": "#/$defs/shapes/repeater"}, + {"$ref": "#/$defs/shapes/rounded-corners"}, + {"$ref": "#/$defs/shapes/stroke"}, + {"$ref": "#/$defs/shapes/transform"}, + {"$ref": "#/$defs/shapes/trim"}, + {"$ref": "#/$defs/shapes/twist"}, + {"$ref": "#/$defs/shapes/merge"}, + {"$ref": "#/$defs/shapes/offset-path"}, + {"$ref": "#/$defs/shapes/zig-zag"}, + {"$ref": "#/$defs/shapes/no-style"} + ] + } +} diff --git a/schema/shapes/shape.json b/schema/shapes/shape.json new file mode 100644 index 00000000..13661cd0 --- /dev/null +++ b/schema/shapes/shape.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Shape", + "description": "Drawable shape", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "d": { + "title": "Direction", + "description": "Direction the shape is drawn as, mostly relevant when using trim path", + "$ref": "#/$defs/constants/shape-direction" + } + } + } + ] +} diff --git a/schema/shapes/stroke-dash.json b/schema/shapes/stroke-dash.json new file mode 100644 index 00000000..f6769d1a --- /dev/null +++ b/schema/shapes/stroke-dash.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Stroke Dash", + "description": "An item used to described the dashe pattern in a stroked path", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "n": { + "title": "Dash Type", + "$ref": "#/$defs/constants/stroke-dash-type", + "default": "d" + }, + "v": { + "title": "Length", + "description": "Length of the dash", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] +} diff --git a/schema/shapes/stroke.json b/schema/shapes/stroke.json new file mode 100644 index 00000000..cc6aeb78 --- /dev/null +++ b/schema/shapes/stroke.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Stroke", + "description": "Solid stroke", + "caniuse": "shape-stroke", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/shapes/base-stroke" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "st" + }, + "c": { + "title": "Color", + "description": "Stroke color", + "$ref": "#/$defs/animated-properties/color-value" + } + }, + "required": [ + "ty", "c" + ] + } + ] +} diff --git a/schema/shapes/transform.json b/schema/shapes/transform.json new file mode 100644 index 00000000..2423ae9f --- /dev/null +++ b/schema/shapes/transform.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Transform Shape", + "description": "Group transform", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "$ref": "#/$defs/helpers/transform" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "tr" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/shapes/trim.json b/schema/shapes/trim.json new file mode 100644 index 00000000..52e5ebc2 --- /dev/null +++ b/schema/shapes/trim.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Trim", + "description": "Trims shapes into a segment", + "caniuse": "shape-trim-path", + "allOf": [ + { + "$ref": "#/$defs/shapes/modifier" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "tm" + }, + "s": { + "title": "Start", + "description": "Segment start", + "$ref": "#/$defs/animated-properties/value" + }, + "e": { + "title": "End", + "description": "Segment end", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + }, + "m": { + "title": "Multiple", + "description": "How to treat multiple copies", + "$ref": "#/$defs/constants/trim-multiple-shapes" + } + }, + "required": [ + "ty", "o", "s", "e" + ] + } + ] +} diff --git a/schema/shapes/twist.json b/schema/shapes/twist.json new file mode 100644 index 00000000..336e0016 --- /dev/null +++ b/schema/shapes/twist.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Twist", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "tw" + }, + "a": { + "title": "Angle", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Center", + "$ref": "#/$defs/animated-properties/multi-dimensional" + } + }, + "required": [ + "ty" + ] + } + ] +} \ No newline at end of file diff --git a/schema/shapes/zig-zag.json b/schema/shapes/zig-zag.json new file mode 100644 index 00000000..4f1b9aa0 --- /dev/null +++ b/schema/shapes/zig-zag.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Zig Zag", + "description": "Changes the edges of affected shapes into a series of peaks and valleys of uniform size", + "allOf": [ + { + "$ref": "#/$defs/shapes/shape-element" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Shape Type", + "type": "string", + "const": "zz" + }, + "r": { + "title": "Frequency", + "description": "Number of ridges per segment", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Amplitude", + "description": "Distance between peaks and troughs", + "$ref": "#/$defs/animated-properties/value" + }, + "pt": { + "title": "Point Type", + "description": "Point type (1 = corner, 2 = smooth)", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [ + "ty" + ] + } + ] +} + diff --git a/schema/styles/bevel-emboss-style.json b/schema/styles/bevel-emboss-style.json new file mode 100644 index 00000000..c26bef76 --- /dev/null +++ b/schema/styles/bevel-emboss-style.json @@ -0,0 +1,82 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Bevel Emboss", + "caniuse": "style-bevel-and-emboss", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 5 + }, + "bs": { + "title": "Bevel Style", + "$ref": "#/$defs/animated-properties/value" + }, + "bt": { + "title": "Technique", + "$ref": "#/$defs/animated-properties/value" + }, + "sr": { + "title": "Strength", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/value" + }, + "sf": { + "title": "Soften", + "$ref": "#/$defs/animated-properties/value" + }, + "ga": { + "title": "Global Angle", + "description": "Use global light", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "description": "Local lighting angle", + "$ref": "#/$defs/animated-properties/value" + }, + "ll": { + "title": "Altitude", + "description": "Local lighting altitude", + "$ref": "#/$defs/animated-properties/value" + }, + "hm": { + "title": "Highlight Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "hc": { + "title": "Highlight Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "ho": { + "title": "Highlight Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "sm": { + "title": "Shadow Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "sc": { + "title": "Shadow Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "so": { + "title": "Shadow Opacity", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/color-overlay-style.json b/schema/styles/color-overlay-style.json new file mode 100644 index 00000000..afa90ed1 --- /dev/null +++ b/schema/styles/color-overlay-style.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Color Overlay", + "caniuse": "style-color-overlay", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 7 + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "so": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/drop-shadow-style.json b/schema/styles/drop-shadow-style.json new file mode 100644 index 00000000..f4473446 --- /dev/null +++ b/schema/styles/drop-shadow-style.json @@ -0,0 +1,62 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Drop Shadow", + "caniuse": "style-drop-shadow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 1 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "description": "Local light angle", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "description": "Blur size", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Distance", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + }, + "lc": { + "title": "Layer Conceal", + "description": "Layer knowck out drop shadow", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/gradient-overlay-style.json b/schema/styles/gradient-overlay-style.json new file mode 100644 index 00000000..e7c40899 --- /dev/null +++ b/schema/styles/gradient-overlay-style.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Gradient Overlay", + "caniuse": "style-gradient-overlay", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 8 + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "gf": { + "title": "Gradient", + "$ref": "#/$defs/animated-properties/gradient-colors" + }, + "gs": { + "title": "Smoothness", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "$ref": "#/$defs/animated-properties/value" + }, + "gt": { + "title": "Gradient Type", + "$ref": "#/$defs/constants/gradient-type" + }, + "re": { + "title": "Reverse", + "$ref": "#/$defs/animated-properties/value" + }, + "al": { + "title": "Align", + "description": "Align with layer", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Scale", + "$ref": "#/$defs/animated-properties/value" + }, + "of": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/inner-glow-style.json b/schema/styles/inner-glow-style.json new file mode 100644 index 00000000..e2b1c82b --- /dev/null +++ b/schema/styles/inner-glow-style.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Inner Glow", + "caniuse": "style-inner-glow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 4 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Range", + "$ref": "#/$defs/animated-properties/value" + }, + "sr": { + "title": "Source", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + }, + "j": { + "title": "Jitter", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} + + + diff --git a/schema/styles/inner-shadow-style.json b/schema/styles/inner-shadow-style.json new file mode 100644 index 00000000..5475d97d --- /dev/null +++ b/schema/styles/inner-shadow-style.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Inner Shadow", + "caniuse": "style-inner-shadow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 2 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "description": "Local light angle", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "description": "Blur size", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Distance", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/layer-style.json b/schema/styles/layer-style.json new file mode 100644 index 00000000..2c4af9d5 --- /dev/null +++ b/schema/styles/layer-style.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Layer Style", + "description": "Style applied to a layer", + "allOf": [ + { + "$ref": "#/$defs/helpers/visual-object" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Style Type", + "type": "integer" + } + }, + "required": ["ty"] + } + ] +} + diff --git a/schema/styles/outer-glow-style.json b/schema/styles/outer-glow-style.json new file mode 100644 index 00000000..125f49e4 --- /dev/null +++ b/schema/styles/outer-glow-style.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Outer Glow", + "caniuse": "style-outer-glow", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 3 + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Range", + "$ref": "#/$defs/animated-properties/value" + }, + "ch": { + "title": "Choke Spread", + "$ref": "#/$defs/animated-properties/value" + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "no": { + "title": "Noise", + "$ref": "#/$defs/animated-properties/value" + }, + "j": { + "title": "Jitter", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/satin-style.json b/schema/styles/satin-style.json new file mode 100644 index 00000000..ab03a8b2 --- /dev/null +++ b/schema/styles/satin-style.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Satin", + "caniuse": "style-satin", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 6 + }, + "bm": { + "title": "Blend Mode", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "o": { + "title": "Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Angle", + "$ref": "#/$defs/animated-properties/value" + }, + "d": { + "title": "Distance", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/value" + }, + "in": { + "title": "Invert", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/styles/stroke-style.json b/schema/styles/stroke-style.json new file mode 100644 index 00000000..c7381739 --- /dev/null +++ b/schema/styles/stroke-style.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Layer Stroke", + "caniuse": "style-stroke", + "description": "Stroke / frame", + "allOf": [ + { + "$ref": "#/$defs/styles/layer-style" + }, + { + "type": "object", + "properties": { + "ty": { + "title": "Type", + "description": "Layer Type", + "type": "integer", + "const": 0 + }, + "s": { + "title": "Size", + "$ref": "#/$defs/animated-properties/value" + }, + "c": { + "title": "Color", + "$ref": "#/$defs/animated-properties/color-value" + } + }, + "required": ["ty"] + } + ] +} diff --git a/schema/text/animated-text-document.json b/schema/text/animated-text-document.json new file mode 100644 index 00000000..319a12c7 --- /dev/null +++ b/schema/text/animated-text-document.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Animated Text Document", + "description": "Animated property representing the text contents", + "properties": { + "k": { + "title": "Keyframes", + "type": "array", + "items": { + "$ref": "#/$defs/text/text-document-keyframe" + } + }, + "x": { + "title": "Expression", + "type": "string" + }, + "sid": { + "title": "Slot ID", + "description": "One of the ID in the file's slots", + "type": "string" + } + }, + "required": ["k"] +} diff --git a/schema/text/character-data.json b/schema/text/character-data.json new file mode 100644 index 00000000..519e7615 --- /dev/null +++ b/schema/text/character-data.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Character Data", + "description": "Defines character shapes", + "properties": { + "ch": { + "title": "Character", + "type": "string", + "default": "" + }, + "fFamily": { + "title": "Font Family", + "type": "string", + "default": "" + }, + "size": { + "title": "Font Size", + "type": "number", + "default": 0 + }, + "style": { + "title": "Font Style", + "type": "string", + "default": "" + }, + "w": { + "title": "Width", + "type": "number", + "default": 0 + }, + "data": { + "title": "Data", + "oneOf": [ + {"$ref": "#/$defs/text/character-shapes"}, + {"$ref": "#/$defs/text/character-precomp"} + ] + } + }, + "required": ["data", "ch", "fFamily", "size", "style", "w"] +} diff --git a/schema/text/character-precomp.json b/schema/text/character-precomp.json new file mode 100644 index 00000000..7fad6a8d --- /dev/null +++ b/schema/text/character-precomp.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Character Precomp", + "description": "Defines a character as a precomp layer", + "properties": { + "refId": { + "title": "Reference Id", + "description": "ID of the precomp as specified in the assets", + "type": "string" + }, + "ks": { + "title": "Transform", + "description": "Layer transform", + "$ref": "#/$defs/helpers/transform" + }, + "ip": { + "title": "In Point", + "description": "Frame when the layer becomes visible", + "type": "number", + "default": 0 + }, + "op": { + "title": "Out Point", + "description": "Frame when the layer becomes invisible", + "type": "number", + "default": 99999 + }, + "sr": { + "title": "Time Stretch", + "type": "number", + "default": 1 + }, + "st": { + "title": "Start Time", + "type": "number", + "default": 0 + } + }, + "required": ["refId"] +} diff --git a/schema/text/character-shapes.json b/schema/text/character-shapes.json new file mode 100644 index 00000000..0e58a25b --- /dev/null +++ b/schema/text/character-shapes.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Character Shape", + "description": "Defines a character as shapes", + "properties": { + "shapes": { + "title": "Shapes", + "description": "Shapes forming the character", + "$ref": "#/$defs/shapes/shape-list" + } + }, + "required": ["shapes"] +} diff --git a/schema/text/font-list.json b/schema/text/font-list.json new file mode 100644 index 00000000..7c657340 --- /dev/null +++ b/schema/text/font-list.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Font List", + "description": "List of fonts", + "allOf": [ + { + "type": "object", + "properties": { + "list": { + "title": "List", + "type": "array", + "items": { + "$ref": "#/$defs/text/font" + } + } + }, + "required": [] + } + ] +} diff --git a/schema/text/font.json b/schema/text/font.json new file mode 100644 index 00000000..ba2dd553 --- /dev/null +++ b/schema/text/font.json @@ -0,0 +1,55 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Font", + "description": "Describes how a font with given settings should be loaded", + "allOf": [ + { + "type": "object", + "properties": { + "ascent": { + "title": "Ascent", + "type": "number", + "description": "Text will be moved down based on this value" + }, + "fFamily": { + "title": "Font Family", + "type": "string", + "default": "sans" + }, + "fName": { + "title": "Name", + "description": "Name used by text documents to reference this font, usually it's `fFamily` followed by `fStyle`", + "type": "string", + "default": "sans-Regular" + }, + "fStyle": { + "title": "Font Style", + "examples": ["Regular", "Bold", "Bold Italic"], + "type": "string", + "default": "Regular" + }, + "fPath": { + "title": "Path", + "type": "string" + }, + "fWeight": { + "title": "Weight", + "type": "string" + }, + "origin": { + "title": "Origin", + "$ref": "#/$defs/constants/font-path-origin" + }, + "fClass": { + "type": "string", + "title": "CSS Class", + "description": "CSS Class applied to text objects using this font" + } + }, + "required": [ + "fFamily", "fName", "fStyle" + ] + } + ] +} diff --git a/schema/text/text-alignment-options.json b/schema/text/text-alignment-options.json new file mode 100644 index 00000000..ccd2d4c5 --- /dev/null +++ b/schema/text/text-alignment-options.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Alignment Options", + "description": "", + "allOf": [ + { + "type": "object", + "properties": { + "a": { + "title": "Alignment", + "description": "Group alignment", + "caniuse": "animators-grouping-alignment", + "$ref": "#/$defs/animated-properties/multi-dimensional" + }, + "g": { + "title": "Grouping", + "description": "Anchor point grouping", + "caniuse": "animators-anchor-point-grouping", + "$ref": "#/$defs/constants/text-grouping" + } + }, + "required": [] + } + ] +} diff --git a/schema/text/text-data.json b/schema/text/text-data.json new file mode 100644 index 00000000..e587194b --- /dev/null +++ b/schema/text/text-data.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Data", + "description": "Contains all the text data and animation", + "allOf": [ + { + "type": "object", + "properties": { + "a": { + "title": "Ranges", + "caniuse": "text-animators", + "type": "array", + "items": { + "$ref": "#/$defs/text/text-range" + } + }, + "d": { + "title": "Document", + "$ref": "#/$defs/text/animated-text-document" + }, + "m": { + "title": "Alignment", + "$ref": "#/$defs/text/text-alignment-options" + }, + "p": { + "title": "Follow Path", + "$ref": "#/$defs/text/text-follow-path" + } + }, + "required": ["a", "d", "m", "p"] + } + ] +} diff --git a/schema/text/text-document-keyframe.json b/schema/text/text-document-keyframe.json new file mode 100644 index 00000000..581cbeed --- /dev/null +++ b/schema/text/text-document-keyframe.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Document Keyframe", + "description": "A keyframe containing a text document", + "properties": { + "s": { + "title": "Start", + "$ref": "#/$defs/text/text-document" + }, + "t": { + "title": "Time", + "type": "number", + "default": 0 + } + }, + "required": ["s", "t"] +} diff --git a/schema/text/text-document.json b/schema/text/text-document.json new file mode 100644 index 00000000..cd26818f --- /dev/null +++ b/schema/text/text-document.json @@ -0,0 +1,91 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Document", + "description": "", + "properties": { + "f": { + "title": "Font Family", + "type": "string", + "default": "" + }, + "fc": { + "title": "Fill Color", + "$ref": "#/$defs/helpers/color", + "default": [ + 0, + 0, + 0 + ] + }, + "sc": { + "title": "Stroke Color", + "$ref": "#/$defs/helpers/color" + }, + "sw": { + "title": "Stroke Width", + "type": "number", + "default": 0 + }, + "of": { + "title": "Stroke Over Fill", + "description": "Render stroke above the fill", + "type": "boolean" + }, + "s": { + "title": "Font Size", + "type": "number", + "default": 10 + }, + "lh": { + "title": "Line Height", + "description": "Distance between lines on multiline or wrapped text", + "type": "number" + }, + "sz": { + "title": "Wrap Size", + "description": "Size of the box containing the text", + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "number" + } + }, + "ps": { + "title": "Wrap Position", + "description": "Position of the box containing the text", + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "number" + } + }, + "t": { + "title": "Text", + "type": "string", + "description": "Text, note that newlines are encoded with \\r", + "default": "" + }, + "j": { + "title": "Justify", + "$ref": "#/$defs/constants/text-justify", + "default": 0 + }, + "ca": { + "title": "Text Caps", + "$ref": "#/$defs/constants/text-caps" + }, + "tr": { + "title": "Tracking", + "description": "Text Tracking", + "type": "number" + }, + "ls": { + "title": "Baseline Shift", + "type": "number" + } + }, + "required": ["f", "fc", "s", "t"] +} diff --git a/schema/text/text-follow-path.json b/schema/text/text-follow-path.json new file mode 100644 index 00000000..59dd9dd6 --- /dev/null +++ b/schema/text/text-follow-path.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Follow Path", + "caniuse": "text-path", + "description": "Uses the path described by a layer mask to put the text on said path.", + "allOf": [ + { + "type": "object", + "properties": { + "m": { + "title": "Mask", + "type": "integer", + "description": "Index of the mask to use" + }, + "f": { + "title": "First Margin", + "$ref": "#/$defs/animated-properties/value" + }, + "l": { + "title": "Last Margin", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Reverse Path", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Force Alignment", + "$ref": "#/$defs/animated-properties/value" + }, + "p": { + "title": "Perpendicular To Path", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] +} diff --git a/schema/text/text-range-selector.json b/schema/text/text-range-selector.json new file mode 100644 index 00000000..efd212d4 --- /dev/null +++ b/schema/text/text-range-selector.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Range Selector", + "caniuse": "animators-range-selectors", + "properties": { + "t": { + "title": "Expressible", + "$ref": "#/$defs/helpers/int-boolean" + }, + "xe": { + "title": "Max Ease", + "$ref": "#/$defs/animated-properties/value" + }, + "ne": { + "title": "Min Ease", + "$ref": "#/$defs/animated-properties/value" + }, + "a": { + "title": "Max Amount", + "$ref": "#/$defs/animated-properties/value" + }, + "b": { + "title": "Based On", + "$ref": "#/$defs/constants/text-based" + }, + "rn": { + "title": "Randomize", + "$ref": "#/$defs/helpers/int-boolean" + }, + "sh": { + "title": "Shape", + "$ref": "#/$defs/constants/text-shape" + }, + "o": { + "title": "Offset", + "$ref": "#/$defs/animated-properties/value" + }, + "r": { + "title": "Range Units", + "caniuse": "range-selectors-units", + "$ref": "#/$defs/constants/text-range-units" + }, + "sm": { + "title": "Selector Smoothness", + "$ref": "#/$defs/animated-properties/value" + }, + "s": { + "title": "Start", + "$ref": "#/$defs/animated-properties/value" + }, + "e": { + "title": "End", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": ["t", "a", "b", "sh"] +} diff --git a/schema/text/text-range.json b/schema/text/text-range.json new file mode 100644 index 00000000..5b5a12a7 --- /dev/null +++ b/schema/text/text-range.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Range", + "description": "Range of text with custom animations and style", + "caniuse": "animators-range-selectors", + "properties": { + "nm": { + "title": "Name", + "type": "string" + }, + "s": { + "title": "Selector", + "$ref": "#/$defs/text/text-range-selector" + }, + "a": { + "title": "Style", + "$ref": "#/$defs/text/text-style" + } + } +} diff --git a/schema/text/text-style.json b/schema/text/text-style.json new file mode 100644 index 00000000..c8f43a53 --- /dev/null +++ b/schema/text/text-style.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Text Style", + "description": "", + "allOf": [ + { + "$ref": "#/$defs/helpers/transform" + }, + { + "type": "object", + "properties": { + "sw": { + "title": "Stroke Width", + "$ref": "#/$defs/animated-properties/value" + }, + "sc": { + "title": "Stroke Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "sh": { + "title": "Stroke Hue", + "$ref": "#/$defs/animated-properties/value" + }, + "ss": { + "title": "Stroke Saturation", + "$ref": "#/$defs/animated-properties/value" + }, + "sb": { + "title": "Stroke Brightness", + "$ref": "#/$defs/animated-properties/value" + }, + "so": { + "title": "Stroke Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "fc": { + "title": "Fill Color", + "$ref": "#/$defs/animated-properties/color-value" + }, + "fh": { + "title": "Fill Hue", + "$ref": "#/$defs/animated-properties/value" + }, + "fs": { + "title": "Fill Saturation", + "$ref": "#/$defs/animated-properties/value" + }, + "fb": { + "title": "Fill Brightness", + "$ref": "#/$defs/animated-properties/value" + }, + "fo": { + "title": "Fill Opacity", + "$ref": "#/$defs/animated-properties/value" + }, + "t": { + "title": "Letter Spacing", + "$ref": "#/$defs/animated-properties/value" + }, + "bl": { + "title": "Blur", + "caniuse": "text-animators-blur", + "$ref": "#/$defs/animated-properties/value" + }, + "ls": { + "title": "Line Spacing", + "$ref": "#/$defs/animated-properties/value" + } + }, + "required": [] + } + ] +} diff --git a/scripts/blockly_generated.js b/scripts/blockly_generated.js new file mode 100644 index 00000000..cbd37f91 --- /dev/null +++ b/scripts/blockly_generated.js @@ -0,0 +1,10398 @@ +Blockly.defineBlocksWithJsonArray([ +{ + "type": "lottie_animation", + "message0": " Animation %1 Name %2 Match Name %3 Version %4 Framerate %5 %6 In Point %7 %8 Out Point %9 %10 Width %11 %12 Height %13 %14 Threedimensional %15 %16 Assets %17 Extra Compositions %18 Fonts %19 Characters %20 Metadata %21 User Metadata %22 Markers %23 Motion Blur %24 Slots %25 Layers %26", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "v", + "check": "value" + }, + { + "type": "field_number", + "name": "fr", + "value": 60 + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "ip", + "value": 0 + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "op", + "value": 60 + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "w", + "value": 512 + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "h", + "value": 512 + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ddd", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "assets", + "check": "assets" + }, + { + "type": "input_statement", + "name": "comps", + "check": "lottie_precomposition" + }, + { + "type": "input_value", + "name": "fonts", + "check": "lottie_font_list" + }, + { + "type": "input_statement", + "name": "chars", + "check": "lottie_character_data" + }, + { + "type": "input_value", + "name": "meta", + "check": "lottie_metadata" + }, + { + "type": "input_value", + "name": "metadata", + "check": "lottie_user_metadata" + }, + { + "type": "input_statement", + "name": "markers" + }, + { + "type": "input_value", + "name": "mb", + "check": "lottie_motion_blur" + }, + { + "type": "input_value", + "name": "slots" + }, + { + "type": "input_statement", + "name": "layers", + "check": "layers" + } + ], + "colour": 260, + "helpUrl": "/lottie-docs/animation/#animation", + "tooltip": "Animation", + "inputsInline": false +}, +{ + "type": "lottie_metadata", + "message0": " Metadata %1 Author %2 Description %3 Theme Color %4 Generator %5", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "a", + "check": "value" + }, + { + "type": "input_value", + "name": "d", + "check": "value" + }, + { + "type": "input_value", + "name": "tc", + "check": "value" + }, + { + "type": "input_value", + "name": "g", + "check": "value" + } + ], + "colour": 260, + "helpUrl": "/lottie-docs/animation/#metadata", + "tooltip": "Metadata", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_motion_blur", + "message0": " Motion Blur %1 Shutter Angle %2 Shutter Phase %3 Samples per Frame %4 Adaptive Sample Limit %5", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "sa", + "check": "value" + }, + { + "type": "input_value", + "name": "sp", + "check": "value" + }, + { + "type": "input_value", + "name": "spf", + "check": "value" + }, + { + "type": "input_value", + "name": "asl", + "check": "value" + } + ], + "colour": 260, + "helpUrl": "/lottie-docs/animation/#motion-blur", + "tooltip": "Motion Blur", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_user_metadata", + "message0": " User Metadata %1 Filename %2 Custom Properties %3", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "filename", + "check": "value" + }, + { + "type": "input_value", + "name": "customProps" + } + ], + "colour": 260, + "helpUrl": "/lottie-docs/animation/#user-metadata", + "tooltip": "User Metadata", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_layer_common", + "message0": " Layer Properties %1 Name %2 Match Name %3 Threedimensional %4 %5 Hidden %6 %7 Index %8 Parent Index %9 Time Stretch %10 In Point %11 %12 Out Point %13 %14 Start Time %15 %16", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "ddd", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ind", + "check": "value" + }, + { + "type": "input_value", + "name": "parent", + "check": "value" + }, + { + "type": "input_value", + "name": "sr", + "check": "value" + }, + { + "type": "field_number", + "name": "ip" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "op" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "st", + "value": 0 + }, + { + "type": "input_dummy" + } + ], + "colour": 0, + "helpUrl": "/lottie-docs/layers/#layer", + "tooltip": "Layer Properties", + "inputsInline": false, + "output": "lottie_layer_common" +}, +{ + "type": "lottie_audio_layer", + "message0": " Audio Layer %1 Layer Properties %2 Type %3 %4 Audio Settings %5 Sound Id %6", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "6" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "au", + "check": "lottie_audio_settings" + }, + { + "type": "input_value", + "name": "refId", + "check": "value" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#audio-layer", + "tooltip": "Audio Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_audio_settings", + "message0": " Audio Settings %1 Level %2", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lv", + "check": "property" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#audio-settings", + "tooltip": "Audio Settings", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_camera_layer", + "message0": " Camera Layer %1 Layer Properties %2 Type %3 %4 Transform %5 Perspective %6", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "13" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "input_value", + "name": "pe", + "check": "property" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#camera-layer", + "tooltip": "Camera Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_data_layer", + "message0": " Data Layer %1 Layer Properties %2 Type %3 %4 Data source Id %5", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "15" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "refId", + "check": "value" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#data-layer", + "tooltip": "Data Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_image_layer", + "message0": " Image Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26 Type %27 %28 Image Id %29 %30", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "2" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "refId", + "text": "" + }, + { + "type": "input_dummy" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#image-layer", + "tooltip": "Image Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_layer", + "message0": " Layer %1 Layer Properties %2 Type %3 %4 Custom Attributes %5 %6", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "field_number", + "name": "ty" + }, + { + "type": "input_dummy" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "custom_attributes", + "check": "object_member" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#layer", + "tooltip": "Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_null_layer", + "message0": " Null Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26 Type %27 %28", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "3" + }, + { + "type": "input_dummy" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#null-layer", + "tooltip": "Null Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_precomposition_layer", + "message0": " Precomposition Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26 Type %27 %28 Reference Id %29 %30 Width %31 %32 Height %33 %34 Time Remapping %35", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "0" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "refId" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "w" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "h" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tm", + "check": "property" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#precomposition-layer", + "tooltip": "Precomposition Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_shape_layer", + "message0": " Shape Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26 Type %27 %28 Shapes %29", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "4" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "shapes", + "check": "shapes" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#shape-layer", + "tooltip": "Shape Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_solid_color_layer", + "message0": " Solid Color Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26 Type %27 %28 Color %29 %30 Height %31 %32 Width %33 %34", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "1" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "sc", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "sh" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "sw" + }, + { + "type": "input_dummy" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#solid-color-layer", + "tooltip": "Solid Color Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_text_layer", + "message0": " Text Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26 Type %27 %28 Data %29", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "5" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "t", + "check": "lottie_text_data" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#text-layer", + "tooltip": "Text Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_visual_layer", + "message0": " Visual Layer %1 Layer Properties %2 Transform %3 Auto Orient %4 %5 Matte Mode %6 %7 Matte Parent %8 Matte Target %9 %10 Has Masks %11 %12 Masks %13 Effects %14 Motion Blur %15 %16 Layer style %17 Blend Mode %18 %19 CSS Class %20 Layer XML ID %21 Layer XML tag name %22 Collapse Transform %23 %24 Collapse Transform %25 %26", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lottie_layer_common", + "check": "lottie_layer_common" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "field_checkbox", + "name": "ao", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "tt", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Alpha", + "1" + ], + [ + "Inverted Alpha", + "2" + ], + [ + "Luma", + "3" + ], + [ + "Inverted Luma", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tp", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "td" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "hasMask" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "masksProperties" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effects" + }, + { + "type": "field_checkbox", + "name": "mb" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "sy", + "check": "styles" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "tg", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "cp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "ct", + "checked": false + }, + { + "type": "input_dummy" + } + ], + "colour": 60, + "helpUrl": "/lottie-docs/layers/#layer", + "tooltip": "Visual Layer", + "inputsInline": false, + "previousStatement": "layers", + "nextStatement": "layers" +}, +{ + "type": "lottie_ellipse", + "message0": " Ellipse %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Direction %14 %15 Position %16 Size %17", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/circle.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "el" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "d", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "1" + ], + [ + "Reversed", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "p", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#ellipse", + "tooltip": "Ellipse", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_fill", + "message0": " Fill %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Opacity %14 Color %15 Fill Rule %16 %17", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/solid/fill-drip.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "fl" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "input_value", + "name": "c", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "r", + "options": [ + [ + "--", + "" + ], + [ + "Non Zero", + "1" + ], + [ + "Even Odd", + "2" + ] + ] + }, + { + "type": "input_dummy" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#fill", + "tooltip": "Fill", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_gradient_fill", + "message0": " Gradient Fill %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12 Start Point %13 End Point %14 Gradient Type %15 %16 Highlight Length %17 Highlight Angle %18 Colors %19 Opacity %20 Fill Rule %21 %22", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "gf" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "e", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "t", + "options": [ + [ + "--", + "" + ], + [ + "Linear", + "1" + ], + [ + "Radial", + "2" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "h", + "check": "property" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "input_value", + "name": "g", + "check": "lottie_gradient_colors" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "r", + "options": [ + [ + "--", + "" + ], + [ + "Non Zero", + "1" + ], + [ + "Even Odd", + "2" + ] + ] + }, + { + "type": "input_dummy" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#gradients", + "tooltip": "Gradient Fill", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_gradient_stroke", + "message0": " Gradient Stroke %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12 Line Cap %13 %14 Line Join %15 %16 Miter Limit %17 Miter Limit %18 Opacity %19 Width %20 Dashes %21 Start Point %22 End Point %23 Gradient Type %24 %25 Highlight Length %26 Highlight Angle %27 Colors %28", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "gs" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "lc", + "options": [ + [ + "--", + "" + ], + [ + "Butt", + "1" + ], + [ + "Round", + "2" + ], + [ + "Square", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "lj", + "options": [ + [ + "--", + "" + ], + [ + "Miter", + "1" + ], + [ + "Round", + "2" + ], + [ + "Bevel", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ml", + "check": "value" + }, + { + "type": "input_value", + "name": "ml2", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "input_value", + "name": "w", + "check": "property" + }, + { + "type": "input_statement", + "name": "d", + "check": "lottie_stroke_dash" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "e", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "t", + "options": [ + [ + "--", + "" + ], + [ + "Linear", + "1" + ], + [ + "Radial", + "2" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "h", + "check": "property" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "input_value", + "name": "g", + "check": "lottie_gradient_colors" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#gradients", + "tooltip": "Gradient Stroke", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_group", + "message0": " Group %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Number Of Properties %14 Shapes %15 Property index %16", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/object-group.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "gr" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_statement", + "name": "it", + "check": "shapes" + }, + { + "type": "input_value", + "name": "cix", + "check": "value" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#group", + "tooltip": "Group", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_no_style", + "message0": " No Style %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "no" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#no-style", + "tooltip": "No Style", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_path", + "message0": " Path %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Direction %14 %15 Shape %16", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/solid/bezier-curve.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "sh" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "d", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "1" + ], + [ + "Reversed", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ks", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#path", + "tooltip": "Path", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_polystar", + "message0": " PolyStar %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Direction %14 %15 Position %16 Outer Radius %17 Outer Roundness %18 Rotation %19 Points %20 Star Type %21 %22 Inner Radius %23 Inner Roundness %24", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/star.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "sr" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "d", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "1" + ], + [ + "Reversed", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "p", + "check": "property" + }, + { + "type": "input_value", + "name": "or", + "check": "property" + }, + { + "type": "input_value", + "name": "os", + "check": "property" + }, + { + "type": "input_value", + "name": "r", + "check": "property" + }, + { + "type": "input_value", + "name": "pt", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "sy", + "options": [ + [ + "--", + "" + ], + [ + "Star", + "1" + ], + [ + "Polygon", + "2" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ir", + "check": "property" + }, + { + "type": "input_value", + "name": "is", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#polystar", + "tooltip": "PolyStar", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_pucker_bloat", + "message0": " Pucker Bloat %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12 Amount %13", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "pb" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#pucker-bloat", + "tooltip": "Pucker Bloat", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_rectangle", + "message0": " Rectangle %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Direction %14 %15 Position %16 Size %17 Rounded %18", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/square.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "rc" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "d", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "1" + ], + [ + "Reversed", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "p", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "r", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#rectangle", + "tooltip": "Rectangle", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_repeater", + "message0": " Repeater %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Copies %14 Offset %15 Composite %16 %17 Transform %18", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/clone.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "rp" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "c", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "m", + "options": [ + [ + "--", + "" + ], + [ + "Below", + "1" + ], + [ + "Above", + "2" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tr", + "check": "lottie_repeater_transform" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#repeater", + "tooltip": "Repeater", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_repeater_transform", + "message0": " Repeater Transform %1 Anchor Point %2 Scale %3 Opacity %4 Skew %5 Skew Axis %6 Start Opacity %7 End Opacity %8", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "input_value", + "name": "sk", + "check": "property" + }, + { + "type": "input_value", + "name": "sa", + "check": "property" + }, + { + "type": "input_value", + "name": "so", + "check": "property" + }, + { + "type": "input_value", + "name": "eo", + "check": "property" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/shapes/#repeater-transform", + "tooltip": "Repeater Transform", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_rounded_corners", + "message0": " Rounded Corners %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12 Radius %13", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "rd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "r", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#rounded-corners", + "tooltip": "Rounded Corners", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_shape_element", + "message0": " Shape Element %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12 Custom Attributes %13 %14", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "ty" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "custom_attributes", + "check": "object_member" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#shape-elements", + "tooltip": "Shape Element", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_stroke", + "message0": " Stroke %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Line Cap %14 %15 Line Join %16 %17 Miter Limit %18 Miter Limit %19 Opacity %20 Width %21 Dashes %22 Color %23", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/solid/border-style.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "st" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "lc", + "options": [ + [ + "--", + "" + ], + [ + "Butt", + "1" + ], + [ + "Round", + "2" + ], + [ + "Square", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "lj", + "options": [ + [ + "--", + "" + ], + [ + "Miter", + "1" + ], + [ + "Round", + "2" + ], + [ + "Bevel", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ml", + "check": "value" + }, + { + "type": "input_value", + "name": "ml2", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "input_value", + "name": "w", + "check": "property" + }, + { + "type": "input_statement", + "name": "d", + "check": "lottie_stroke_dash" + }, + { + "type": "input_value", + "name": "c", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#stroke", + "tooltip": "Stroke", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_stroke_dash", + "message0": " Stroke Dash %1 Name %2 Match Name %3 Dash Type %4 %5 Length %6", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "n", + "options": [ + [ + "--", + "" + ], + [ + "Dash", + "d" + ], + [ + "Gap", + "g" + ], + [ + "Offset", + "o" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 0, + "helpUrl": "/lottie-docs/shapes/#stroke-dashes", + "tooltip": "Stroke Dash", + "inputsInline": false, + "previousStatement": "lottie_stroke_dash", + "nextStatement": "lottie_stroke_dash" +}, +{ + "type": "lottie_transform_shape", + "message0": " Transform Shape %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Anchor Point %14 Position %15 Scale %16 Opacity %17 Skew %18 Skew Axis %19", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/solid/arrows-alt.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "tr" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "input_value", + "name": "p", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "input_value", + "name": "sk", + "check": "property" + }, + { + "type": "input_value", + "name": "sa", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#transform-shape", + "tooltip": "Transform Shape", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_trim", + "message0": " Trim %1 %2 Name %3 Match Name %4 Hidden %5 %6 Shape Type %7 %8 Blend Mode %9 %10 Property index %11 CSS Class %12 Layer XML ID %13 Start %14 End %15 Offset %16 Multiple %17 %18", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/star-half.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "tm" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "e", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "m", + "options": [ + [ + "--", + "" + ], + [ + "Simultaneously", + "1" + ], + [ + "Individually", + "2" + ] + ] + }, + { + "type": "input_dummy" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#trim-path", + "tooltip": "Trim", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_zig_zag", + "message0": " Zig Zag %1 Name %2 Match Name %3 Hidden %4 %5 Shape Type %6 %7 Blend Mode %8 %9 Property index %10 CSS Class %11 Layer XML ID %12 Frequency %13 Amplitude %14 Point Type %15", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "hd" + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "zz" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "bm", + "options": [ + [ + "--", + "" + ], + [ + "Normal", + "0" + ], + [ + "Multiply", + "1" + ], + [ + "Screen", + "2" + ], + [ + "Overlay", + "3" + ], + [ + "Darken", + "4" + ], + [ + "Lighten", + "5" + ], + [ + "Color Dodge", + "6" + ], + [ + "Color Burn", + "7" + ], + [ + "Hard Light", + "8" + ], + [ + "Soft Light", + "9" + ], + [ + "Difference", + "10" + ], + [ + "Exclusion", + "11" + ], + [ + "Hue", + "12" + ], + [ + "Saturation", + "13" + ], + [ + "Color", + "14" + ], + [ + "Luminosity", + "15" + ], + [ + "Add", + "16" + ], + [ + "Hard Mix", + "17" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "cl", + "check": "value" + }, + { + "type": "input_value", + "name": "ln", + "check": "value" + }, + { + "type": "input_value", + "name": "r", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "pt", + "check": "property" + } + ], + "colour": 120, + "helpUrl": "/lottie-docs/shapes/#zig-zag", + "tooltip": "Zig Zag", + "inputsInline": false, + "previousStatement": "shapes", + "nextStatement": "shapes" +}, +{ + "type": "lottie_asset", + "message0": " Asset %1 ID %2 %3 Name %4", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "id", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/assets/#assets", + "tooltip": "Asset", + "inputsInline": false, + "previousStatement": "assets", + "nextStatement": "assets" +}, +{ + "type": "lottie_data_source", + "message0": " Data source %1 ID %2 %3 Name %4 Path %5 File name %6 %7 Embedded %8 %9 Type %10 %11", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "id", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "u", + "check": "value" + }, + { + "type": "field_input", + "name": "p", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "e", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "field_label_serializable", + "name": "t", + "text": "3" + }, + { + "type": "input_dummy" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/assets/#data-source", + "tooltip": "Data source", + "inputsInline": false, + "previousStatement": "assets", + "nextStatement": "assets" +}, +{ + "type": "lottie_file_asset", + "message0": " File Asset %1 ID %2 %3 Name %4 Path %5 File name %6 %7 Embedded %8 %9", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "id", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "u", + "check": "value" + }, + { + "type": "field_input", + "name": "p", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "e", + "checked": false + }, + { + "type": "input_dummy" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/assets/#data-source", + "tooltip": "File Asset", + "inputsInline": false, + "previousStatement": "assets", + "nextStatement": "assets" +}, +{ + "type": "lottie_image", + "message0": " Image %1 %2 ID %3 %4 Name %5 Path %6 File name %7 %8 Embedded %9 %10 Width %11 Height %12 Type %13 %14 Slot ID %15", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/image.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "id", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "u", + "check": "value" + }, + { + "type": "field_input", + "name": "p", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "e", + "checked": false + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "w", + "check": "value" + }, + { + "type": "input_value", + "name": "h", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "t", + "text": "seq" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "sid", + "check": "value" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/assets/#image", + "tooltip": "Image", + "inputsInline": false, + "previousStatement": "assets", + "nextStatement": "assets" +}, +{ + "type": "lottie_precomposition", + "message0": " Precomposition %1 %2 ID %3 %4 Name %5 Layers %6 Framerate %7 Extra %8 %9", + "args0": [ + { + "type": "field_image", + "src": "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/svgs/regular/folder-open.svg", + "width": 16, + "height": 16 + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "id", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_statement", + "name": "layers", + "check": "layers" + }, + { + "type": "input_value", + "name": "fr", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "xt", + "checked": false + }, + { + "type": "input_dummy" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/assets/#precomposition", + "tooltip": "Precomposition", + "inputsInline": false, + "previousStatement": "assets", + "nextStatement": "assets" +}, +{ + "type": "lottie_sound", + "message0": " Sound %1 ID %2 %3 Name %4 Path %5 File name %6 %7 Embedded %8 %9", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "id", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "u", + "check": "value" + }, + { + "type": "field_input", + "name": "p", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "e", + "checked": false + }, + { + "type": "input_dummy" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/assets/#sound", + "tooltip": "Sound", + "inputsInline": false, + "previousStatement": "assets", + "nextStatement": "assets" +}, +{ + "type": "lottie_displacement_map_effect", + "message0": " Displacement Map Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "27" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#displacement-map-effect", + "tooltip": "Displacement Map Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_drop_shadow_effect", + "message0": " Drop Shadow Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "25" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#drop-shadow-effect", + "tooltip": "Drop Shadow Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_effect", + "message0": " Effect %1 Name %2 Match Name %3 Effect Values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10 Custom Attributes %11 %12", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef", + "check": "effect_values" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_number", + "name": "ty" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + }, + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "custom_attributes", + "check": "object_member" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#effects", + "tooltip": "Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_fill_effect", + "message0": " Fill Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "21" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#fill-effect", + "tooltip": "Fill Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_gaussian_blur_effect", + "message0": " Gaussian Blur Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "29" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#gaussian-blur-effect", + "tooltip": "Gaussian Blur Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_matte3_effect", + "message0": " Set Matte Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "28" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#matte3-effect", + "tooltip": "Set Matte Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_mesh_warp_effect", + "message0": " Mesh Warp Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "31" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#mesh-warp-effect", + "tooltip": "Mesh Warp Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_pro_levels_effect", + "message0": " Pro Levels Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "24" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#pro-levels-effect", + "tooltip": "Pro Levels Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_puppet_effect", + "message0": " Puppet Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "34" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#puppet-effect", + "tooltip": "Puppet Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_radial_wipe_effect", + "message0": " Radial Wipe %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "26" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#radial-wipe-effect", + "tooltip": "Radial Wipe", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_spherize_effect", + "message0": " Spherize Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "33" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#spherize-effect", + "tooltip": "Spherize Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_stroke_effect", + "message0": " Stroke Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "22" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#stroke-effect", + "tooltip": "Stroke Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_tint_effect", + "message0": " Tint Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "20" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#tint-effect", + "tooltip": "Tint Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_tritone_effect", + "message0": " Tritone Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "23" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#tritone-effect", + "tooltip": "Tritone Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_twirl_effect", + "message0": " Twirl Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "30" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#twirl-effect", + "tooltip": "Twirl Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_wavy_effect", + "message0": " Wavy Effect %1 Name %2 Match Name %3 Effect values %4 Property Count %5 Effect Index %6 Type %7 %8 Enabled %9 %10", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_statement", + "name": "ef" + }, + { + "type": "input_value", + "name": "np", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "32" + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "en", + "checked": true + }, + { + "type": "input_dummy" + } + ], + "colour": 330, + "helpUrl": "/lottie-docs/effects/#wavy-effect", + "tooltip": "Wavy Effect", + "inputsInline": false, + "previousStatement": "effects", + "nextStatement": "effects" +}, +{ + "type": "lottie_effect_value_angle", + "message0": " Effect Value Angle %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "1" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#angle", + "tooltip": "Effect Value Angle", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_checkbox", + "message0": " Effect Value Checkbox %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "4" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#checkbox", + "tooltip": "Effect Value Checkbox", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_color", + "message0": " Effect Value Color %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "2" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#color", + "tooltip": "Effect Value Color", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_drop_down", + "message0": " Effect Value Drop Down %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "7" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#drop-down", + "tooltip": "Effect Value Drop Down", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_effect_value", + "message0": " Effect Value %1 Name %2 Match Name %3 Effect Index %4 Type %5", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "input_value", + "name": "ty", + "check": "value" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#effect-values", + "tooltip": "Effect Value", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_ignored", + "message0": " Ignored Value %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "6" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "value" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#ignored", + "tooltip": "Ignored Value", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_layer", + "message0": " Effect Value Layer %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "10" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#layer", + "tooltip": "Effect Value Layer", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_no_value", + "message0": " Effect No Value %1", + "args0": [ + { + "type": "input_dummy" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#no-value", + "tooltip": "Effect No Value", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_point", + "message0": " Effect Value Point %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "3" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#point", + "tooltip": "Effect Value Point", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_effect_value_slider", + "message0": " Effect Value Slider %1 Name %2 Match Name %3 Effect Index %4 Type %5 %6 Value %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "mn", + "check": "value" + }, + { + "type": "input_value", + "name": "ix", + "check": "value" + }, + { + "type": "field_label_serializable", + "name": "ty", + "text": "0" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "v", + "check": "property" + } + ], + "colour": 300, + "helpUrl": "/lottie-docs/effects/#slider", + "tooltip": "Effect Value Slider", + "inputsInline": false, + "previousStatement": "effect-values", + "nextStatement": "effect-values" +}, +{ + "type": "lottie_animated_text_document", + "message0": " Animated Text Document %1 Keyframes %2 Expression %3 Slot ID %4", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "k", + "check": "lottie_text_document_keyframe" + }, + { + "type": "input_value", + "name": "x", + "check": "value" + }, + { + "type": "input_value", + "name": "sid", + "check": "value" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#animated-text-document", + "tooltip": "Animated Text Document", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_character_data", + "message0": " Character Data %1 Character %2 %3 Font Family %4 %5 Font Size %6 %7 Font Style %8 %9 Width %10 %11", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "ch", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "fFamily", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "size", + "value": 0 + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "style", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "w", + "value": 0 + }, + { + "type": "input_dummy" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#character-data", + "tooltip": "Character Data", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_character_precomp", + "message0": " Character Precomp %1 Reference Id %2 %3 Transform %4 In Point %5 Out Point %6 Time Stretch %7 Start Time %8", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "refId" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ks", + "check": "lottie_transform" + }, + { + "type": "input_value", + "name": "ip", + "check": "value" + }, + { + "type": "input_value", + "name": "op", + "check": "value" + }, + { + "type": "input_value", + "name": "sr", + "check": "value" + }, + { + "type": "input_value", + "name": "st", + "check": "value" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#character-precomp", + "tooltip": "Character Precomp", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_character_shapes", + "message0": " Character Shape %1 Shapes %2", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "shapes", + "check": "shapes" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#character-shapes", + "tooltip": "Character Shape", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_font", + "message0": " Font %1 Ascent %2 Font Family %3 %4 Name %5 %6 Font Style %7 %8 Path %9 Weight %10 Origin %11 %12 CSS Class %13", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "ascent", + "check": "value" + }, + { + "type": "field_input", + "name": "fFamily", + "text": "sans" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "fName", + "text": "sans-Regular" + }, + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "fStyle", + "text": "Regular" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "fPath", + "check": "value" + }, + { + "type": "input_value", + "name": "fWeight", + "check": "value" + }, + { + "type": "field_dropdown", + "name": "origin", + "options": [ + [ + "--", + "" + ], + [ + "Local", + "0" + ], + [ + "Css Url", + "1" + ], + [ + "Script Url", + "2" + ], + [ + "Font Url", + "3" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "fClass", + "check": "value" + } + ], + "colour": 30, + "helpUrl": "/lottie-docs/text/#font-list", + "tooltip": "Font", + "inputsInline": false, + "previousStatement": "lottie_font", + "nextStatement": "lottie_font" +}, +{ + "type": "lottie_font_list", + "message0": " Font List %1 List %2", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "list", + "check": "lottie_font" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#font-list", + "tooltip": "Font List", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_alignment_options", + "message0": " Text Alignment Options %1 Alignment %2 Grouping %3 %4", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "g", + "options": [ + [ + "--", + "" + ], + [ + "Characters", + "1" + ], + [ + "Word", + "2" + ], + [ + "Line", + "3" + ], + [ + "All", + "4" + ] + ] + }, + { + "type": "input_dummy" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-alignment-options", + "tooltip": "Text Alignment Options", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_data", + "message0": " Text Data %1 Ranges %2 Document %3 Alignment %4 Follow Path %5", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_statement", + "name": "a", + "check": "lottie_text_range" + }, + { + "type": "input_value", + "name": "d", + "check": "lottie_animated_text_document" + }, + { + "type": "input_value", + "name": "m", + "check": "lottie_text_alignment_options" + }, + { + "type": "input_value", + "name": "p", + "check": "lottie_text_follow_path" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-data", + "tooltip": "Text Data", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_document", + "message0": " Text Document %1 Font Family %2 %3 Fill Color %4 Stroke Color %5 Stroke Width %6 Stroke Over Fill %7 %8 Font Size %9 %10 Line Height %11 Wrap Size %12 Wrap Position %13 Text %14 %15 Justify %16 %17 Text Caps %18 %19 Tracking %20 Baseline Shift %21", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_input", + "name": "f", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "fc", + "check": "value" + }, + { + "type": "input_value", + "name": "sc", + "check": "value" + }, + { + "type": "input_value", + "name": "sw", + "check": "value" + }, + { + "type": "field_checkbox", + "name": "of" + }, + { + "type": "input_dummy" + }, + { + "type": "field_number", + "name": "s", + "value": 10 + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "lh", + "check": "value" + }, + { + "type": "input_value", + "name": "sz", + "check": "color" + }, + { + "type": "input_value", + "name": "ps", + "check": "color" + }, + { + "type": "field_input", + "name": "t", + "text": "" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "j", + "options": [ + [ + "--", + "" + ], + [ + "Left", + "0" + ], + [ + "Right", + "1" + ], + [ + "Center", + "2" + ], + [ + "Justify with Last Line Left", + "3" + ], + [ + "Justify with Last Line Right", + "4" + ], + [ + "Justify with Last Line Center", + "5" + ], + [ + "Justify with Last Line Full", + "6" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "ca", + "options": [ + [ + "--", + "" + ], + [ + "Regular", + "0" + ], + [ + "All Caps", + "1" + ], + [ + "Small Caps", + "2" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "tr", + "check": "value" + }, + { + "type": "input_value", + "name": "ls", + "check": "value" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-document", + "tooltip": "Text Document", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_document_keyframe", + "message0": " Text Document Keyframe %1 Start %2 Time %3 %4", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "s", + "check": "lottie_text_document" + }, + { + "type": "field_number", + "name": "t", + "value": 0 + }, + { + "type": "input_dummy" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-document-keyframe", + "tooltip": "Text Document Keyframe", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_follow_path", + "message0": " Text Follow Path %1 Mask %2 First Margin %3 Last Margin %4 Reverse Path %5 Force Alignment %6 Perpendicular To Path %7", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "m", + "check": "value" + }, + { + "type": "input_value", + "name": "f", + "check": "property" + }, + { + "type": "input_value", + "name": "l", + "check": "property" + }, + { + "type": "input_value", + "name": "r", + "check": "property" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "input_value", + "name": "p", + "check": "property" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-follow-path", + "tooltip": "Text Follow Path", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_range", + "message0": " Text Range %1 Name %2 Selector %3 Style %4", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "nm", + "check": "value" + }, + { + "type": "input_value", + "name": "s", + "check": "lottie_text_range_selector" + }, + { + "type": "input_value", + "name": "a", + "check": "lottie_text_style" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-range", + "tooltip": "Text Range", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_range_selector", + "message0": " Text Range Selector %1 Expressible %2 %3 Max Ease %4 Min Ease %5 Max Amount %6 Based On %7 %8 Randomize %9 %10 Shape %11 %12 Offset %13 Range Units %14 %15 Selector Smoothness %16 Start %17 End %18", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "t" + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "xe", + "check": "property" + }, + { + "type": "input_value", + "name": "ne", + "check": "property" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "b", + "options": [ + [ + "--", + "" + ], + [ + "Characters", + "1" + ], + [ + "Character Excluding Spaces", + "2" + ], + [ + "Words", + "3" + ], + [ + "Lines", + "4" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "field_checkbox", + "name": "rn" + }, + { + "type": "input_dummy" + }, + { + "type": "field_dropdown", + "name": "sh", + "options": [ + [ + "--", + "" + ], + [ + "Square", + "1" + ], + [ + "Ramp Up", + "2" + ], + [ + "Ramp Down", + "3" + ], + [ + "Triangle", + "4" + ], + [ + "Round", + "5" + ], + [ + "Smooth", + "6" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "field_dropdown", + "name": "r", + "options": [ + [ + "--", + "" + ], + [ + "Percent", + "1" + ], + [ + "Index", + "2" + ] + ] + }, + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "sm", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "e", + "check": "property" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-range-selector", + "tooltip": "Text Range Selector", + "inputsInline": false, + "output": null +}, +{ + "type": "lottie_text_style", + "message0": " Text Style %1 Anchor Point %2 Scale %3 Opacity %4 Skew %5 Skew Axis %6 Stroke Width %7 Stroke Color %8 Stroke Hue %9 Stroke Saturation %10 Stroke Brightness %11 Stroke Opacity %12 Fill Color %13 Fill Hue %14 Fill Saturation %15 Fill Brightness %16 Fill Opacity %17 Letter Spacing %18 Blur %19 Line Spacing %20", + "args0": [ + { + "type": "input_dummy" + }, + { + "type": "input_value", + "name": "a", + "check": "property" + }, + { + "type": "input_value", + "name": "s", + "check": "property" + }, + { + "type": "input_value", + "name": "o", + "check": "property" + }, + { + "type": "input_value", + "name": "sk", + "check": "property" + }, + { + "type": "input_value", + "name": "sa", + "check": "property" + }, + { + "type": "input_value", + "name": "sw", + "check": "property" + }, + { + "type": "input_value", + "name": "sc", + "check": "property" + }, + { + "type": "input_value", + "name": "sh", + "check": "property" + }, + { + "type": "input_value", + "name": "ss", + "check": "property" + }, + { + "type": "input_value", + "name": "sb", + "check": "property" + }, + { + "type": "input_value", + "name": "so", + "check": "property" + }, + { + "type": "input_value", + "name": "fc", + "check": "property" + }, + { + "type": "input_value", + "name": "fh", + "check": "property" + }, + { + "type": "input_value", + "name": "fs", + "check": "property" + }, + { + "type": "input_value", + "name": "fb", + "check": "property" + }, + { + "type": "input_value", + "name": "fo", + "check": "property" + }, + { + "type": "input_value", + "name": "t", + "check": "property" + }, + { + "type": "input_value", + "name": "bl", + "check": "property" + }, + { + "type": "input_value", + "name": "ls", + "check": "property" + } + ], + "colour": 200, + "helpUrl": "/lottie-docs/text/#text-style", + "tooltip": "Text Style", + "inputsInline": false, + "output": null +}, +]); + +const generated_toolbox = { + "kind": "categoryToolbox", + "contents": [ + { + "kind": "category", + "name": "Animation", + "colour": 260, + "contents": [ + { + "kind": "block", + "type": "lottie_animation", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_metadata" + }, + { + "kind": "block", + "type": "lottie_motion_blur" + }, + { + "kind": "block", + "type": "lottie_user_metadata" + } + ] + }, + { + "kind": "category", + "name": "Layers", + "colour": 60, + "contents": [ + { + "kind": "block", + "type": "lottie_layer_common", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_audio_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_audio_settings" + }, + { + "kind": "block", + "type": "lottie_camera_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_data_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_image_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_null_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_precomposition_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_shape_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_solid_color_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_text_layer", + "blockxml": "60" + }, + { + "kind": "block", + "type": "lottie_visual_layer", + "blockxml": "60" + } + ] + }, + { + "kind": "category", + "name": "Shapes", + "colour": 120, + "contents": [ + { + "kind": "block", + "type": "lottie_ellipse", + "blockxml": "00100100" + }, + { + "kind": "block", + "type": "lottie_fill", + "blockxml": "000100" + }, + { + "kind": "block", + "type": "lottie_gradient_fill", + "blockxml": "" + }, + { + "kind": "block", + "type": "lottie_gradient_stroke", + "blockxml": "" + }, + { + "kind": "block", + "type": "lottie_group" + }, + { + "kind": "block", + "type": "lottie_no_style" + }, + { + "kind": "block", + "type": "lottie_path" + }, + { + "kind": "block", + "type": "lottie_polystar", + "blockxml": "00510000" + }, + { + "kind": "block", + "type": "lottie_pucker_bloat" + }, + { + "kind": "block", + "type": "lottie_rectangle", + "blockxml": "001001000" + }, + { + "kind": "block", + "type": "lottie_repeater", + "blockxml": "" + }, + { + "kind": "block", + "type": "lottie_repeater_transform" + }, + { + "kind": "block", + "type": "lottie_rounded_corners" + }, + { + "kind": "block", + "type": "lottie_shape_element" + }, + { + "kind": "block", + "type": "lottie_stroke", + "blockxml": "0001001" + }, + { + "kind": "block", + "type": "lottie_stroke_dash" + }, + { + "kind": "block", + "type": "lottie_transform_shape", + "blockxml": "100100100" + }, + { + "kind": "block", + "type": "lottie_trim" + }, + { + "kind": "block", + "type": "lottie_zig_zag" + } + ] + }, + { + "kind": "category", + "name": "Assets", + "colour": 30, + "contents": [ + { + "kind": "block", + "type": "lottie_asset" + }, + { + "kind": "block", + "type": "lottie_data_source" + }, + { + "kind": "block", + "type": "lottie_file_asset" + }, + { + "kind": "block", + "type": "lottie_image" + }, + { + "kind": "block", + "type": "lottie_precomposition" + }, + { + "kind": "block", + "type": "lottie_sound" + } + ] + }, + { + "kind": "category", + "name": "Effects", + "colour": 330, + "contents": [ + { + "kind": "block", + "type": "lottie_displacement_map_effect" + }, + { + "kind": "block", + "type": "lottie_drop_shadow_effect" + }, + { + "kind": "block", + "type": "lottie_effect" + }, + { + "kind": "block", + "type": "lottie_fill_effect" + }, + { + "kind": "block", + "type": "lottie_gaussian_blur_effect" + }, + { + "kind": "block", + "type": "lottie_matte3_effect" + }, + { + "kind": "block", + "type": "lottie_mesh_warp_effect" + }, + { + "kind": "block", + "type": "lottie_pro_levels_effect" + }, + { + "kind": "block", + "type": "lottie_puppet_effect" + }, + { + "kind": "block", + "type": "lottie_radial_wipe_effect" + }, + { + "kind": "block", + "type": "lottie_spherize_effect" + }, + { + "kind": "block", + "type": "lottie_stroke_effect" + }, + { + "kind": "block", + "type": "lottie_tint_effect" + }, + { + "kind": "block", + "type": "lottie_tritone_effect" + }, + { + "kind": "block", + "type": "lottie_twirl_effect" + }, + { + "kind": "block", + "type": "lottie_wavy_effect" + } + ] + }, + { + "kind": "category", + "name": "Effect Values", + "colour": 300, + "contents": [ + { + "kind": "block", + "type": "lottie_effect_value_angle" + }, + { + "kind": "block", + "type": "lottie_effect_value_checkbox" + }, + { + "kind": "block", + "type": "lottie_effect_value_color" + }, + { + "kind": "block", + "type": "lottie_effect_value_drop_down" + }, + { + "kind": "block", + "type": "lottie_effect_value_effect_value" + }, + { + "kind": "block", + "type": "lottie_effect_value_ignored" + }, + { + "kind": "block", + "type": "lottie_effect_value_layer" + }, + { + "kind": "block", + "type": "lottie_effect_value_no_value" + }, + { + "kind": "block", + "type": "lottie_effect_value_point" + }, + { + "kind": "block", + "type": "lottie_effect_value_slider" + } + ] + }, + { + "kind": "category", + "name": "Text", + "colour": 200, + "contents": [ + { + "kind": "block", + "type": "lottie_animated_text_document" + }, + { + "kind": "block", + "type": "lottie_character_data" + }, + { + "kind": "block", + "type": "lottie_character_precomp" + }, + { + "kind": "block", + "type": "lottie_character_shapes" + }, + { + "kind": "block", + "type": "lottie_font" + }, + { + "kind": "block", + "type": "lottie_font_list" + }, + { + "kind": "block", + "type": "lottie_text_alignment_options" + }, + { + "kind": "block", + "type": "lottie_text_data", + "blockxml": "" + }, + { + "kind": "block", + "type": "lottie_text_document" + }, + { + "kind": "block", + "type": "lottie_text_document_keyframe", + "blockxml": "" + }, + { + "kind": "block", + "type": "lottie_text_follow_path" + }, + { + "kind": "block", + "type": "lottie_text_range" + }, + { + "kind": "block", + "type": "lottie_text_range_selector" + }, + { + "kind": "block", + "type": "lottie_text_style" + } + ] + } + ] +}; + +class GeneratedGenerator { +lottie_animation(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'v': this.input_to_json(block, 'v'), + 'fr': Number(block.getFieldValue('fr')), + 'ip': Number(block.getFieldValue('ip')), + 'op': Number(block.getFieldValue('op')), + 'w': Number(block.getFieldValue('w')), + 'h': Number(block.getFieldValue('h')), + 'ddd': 'TRUE' == block.getFieldValue('ddd') ? 1 : 0, + 'assets': this.statements_to_json(block, 'assets', false), + 'comps': this.statements_to_json(block, 'comps', false), + 'fonts': this.input_to_json(block, 'fonts'), + 'chars': this.statements_to_json(block, 'chars', true), + 'meta': this.input_to_json(block, 'meta'), + 'metadata': this.input_to_json(block, 'metadata'), + 'markers': this.statements_to_json(block, 'markers', false), + 'mb': this.input_to_json(block, 'mb'), + 'slots': this.input_to_json(block, 'slots'), + 'layers': this.statements_to_json(block, 'layers', false) + }; +} +lottie_metadata(block) +{ + return { + 'a': this.input_to_json(block, 'a'), + 'd': this.input_to_json(block, 'd'), + 'tc': this.input_to_json(block, 'tc'), + 'g': this.input_to_json(block, 'g') + }; +} +lottie_motion_blur(block) +{ + return { + 'sa': this.input_to_json(block, 'sa'), + 'sp': this.input_to_json(block, 'sp'), + 'spf': this.input_to_json(block, 'spf'), + 'asl': this.input_to_json(block, 'asl') + }; +} +lottie_user_metadata(block) +{ + return { + 'filename': this.input_to_json(block, 'filename'), + 'customProps': this.input_to_json(block, 'customProps') + }; +} +lottie_layer_common(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ddd': 'TRUE' == block.getFieldValue('ddd') ? 1 : 0, + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ind': this.input_to_json(block, 'ind'), + 'parent': this.input_to_json(block, 'parent'), + 'sr': this.input_to_json(block, 'sr'), + 'ip': Number(block.getFieldValue('ip')), + 'op': Number(block.getFieldValue('op')), + 'st': Number(block.getFieldValue('st')) + }; +} +lottie_audio_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ty': Number(block.getFieldValue('ty')), + 'au': this.input_to_json(block, 'au'), + 'refId': this.input_to_json(block, 'refId') + }; +} +lottie_audio_settings(block) +{ + return { + 'lv': this.input_to_json(block, 'lv') + }; +} +lottie_camera_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ty': Number(block.getFieldValue('ty')), + 'ks': this.input_to_json(block, 'ks'), + 'pe': this.input_to_json(block, 'pe') + }; +} +lottie_data_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ty': Number(block.getFieldValue('ty')), + 'refId': this.input_to_json(block, 'refId') + }; +} +lottie_image_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0, + 'ty': Number(block.getFieldValue('ty')), + 'refId': block.getFieldValue('refId') + }; +} +lottie_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ty': Number(block.getFieldValue('ty')), + ...this.object_members_to_json(block, 'custom_attributes') + }; +} +lottie_null_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0, + 'ty': Number(block.getFieldValue('ty')) + }; +} +lottie_precomposition_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0, + 'ty': Number(block.getFieldValue('ty')), + 'refId': block.getFieldValue('refId'), + 'w': Number(block.getFieldValue('w')), + 'h': Number(block.getFieldValue('h')), + 'tm': this.input_to_json(block, 'tm') + }; +} +lottie_shape_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0, + 'ty': Number(block.getFieldValue('ty')), + 'shapes': this.statements_to_json(block, 'shapes', false) + }; +} +lottie_solid_color_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0, + 'ty': Number(block.getFieldValue('ty')), + 'sc': block.getFieldValue('sc'), + 'sh': Number(block.getFieldValue('sh')), + 'sw': Number(block.getFieldValue('sw')) + }; +} +lottie_text_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0, + 'ty': Number(block.getFieldValue('ty')), + 't': this.input_to_json(block, 't') + }; +} +lottie_visual_layer(block) +{ + return { + ...this.input_to_json(block, 'lottie_layer_common'), + 'ks': this.input_to_json(block, 'ks'), + 'ao': 'TRUE' == block.getFieldValue('ao') ? 1 : 0, + 'tt': block.getFieldValue('tt') === '' ? undefined : Number(block.getFieldValue('tt')), + 'tp': this.input_to_json(block, 'tp'), + 'td': 'TRUE' == block.getFieldValue('td') ? 1 : 0, + 'hasMask': 'TRUE' == block.getFieldValue('hasMask'), + 'masksProperties': this.statements_to_json(block, 'masksProperties', false), + 'ef': this.statements_to_json(block, 'ef', false), + 'mb': 'TRUE' == block.getFieldValue('mb'), + 'sy': this.statements_to_json(block, 'sy', false), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'tg': this.input_to_json(block, 'tg'), + 'cp': 'TRUE' == block.getFieldValue('cp'), + 'ct': 'TRUE' == block.getFieldValue('ct') ? 1 : 0 + }; +} +lottie_ellipse(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'd': block.getFieldValue('d') === '' ? undefined : Number(block.getFieldValue('d')), + 'p': this.input_to_json(block, 'p'), + 's': this.input_to_json(block, 's') + }; +} +lottie_fill(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'o': this.input_to_json(block, 'o'), + 'c': this.input_to_json(block, 'c'), + 'r': block.getFieldValue('r') === '' ? undefined : Number(block.getFieldValue('r')) + }; +} +lottie_gradient_fill(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 's': this.input_to_json(block, 's'), + 'e': this.input_to_json(block, 'e'), + 't': block.getFieldValue('t') === '' ? undefined : Number(block.getFieldValue('t')), + 'h': this.input_to_json(block, 'h'), + 'a': this.input_to_json(block, 'a'), + 'g': this.input_to_json(block, 'g'), + 'o': this.input_to_json(block, 'o'), + 'r': block.getFieldValue('r') === '' ? undefined : Number(block.getFieldValue('r')) + }; +} +lottie_gradient_stroke(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'lc': block.getFieldValue('lc') === '' ? undefined : Number(block.getFieldValue('lc')), + 'lj': block.getFieldValue('lj') === '' ? undefined : Number(block.getFieldValue('lj')), + 'ml': this.input_to_json(block, 'ml'), + 'ml2': this.input_to_json(block, 'ml2'), + 'o': this.input_to_json(block, 'o'), + 'w': this.input_to_json(block, 'w'), + 'd': this.statements_to_json(block, 'd', false), + 's': this.input_to_json(block, 's'), + 'e': this.input_to_json(block, 'e'), + 't': block.getFieldValue('t') === '' ? undefined : Number(block.getFieldValue('t')), + 'h': this.input_to_json(block, 'h'), + 'a': this.input_to_json(block, 'a'), + 'g': this.input_to_json(block, 'g') + }; +} +lottie_group(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'np': this.input_to_json(block, 'np'), + 'it': this.statements_to_json(block, 'it', false), + 'cix': this.input_to_json(block, 'cix') + }; +} +lottie_no_style(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln') + }; +} +lottie_path(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'd': block.getFieldValue('d') === '' ? undefined : Number(block.getFieldValue('d')), + 'ks': this.input_to_json(block, 'ks') + }; +} +lottie_polystar(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'd': block.getFieldValue('d') === '' ? undefined : Number(block.getFieldValue('d')), + 'p': this.input_to_json(block, 'p'), + 'or': this.input_to_json(block, 'or'), + 'os': this.input_to_json(block, 'os'), + 'r': this.input_to_json(block, 'r'), + 'pt': this.input_to_json(block, 'pt'), + 'sy': block.getFieldValue('sy') === '' ? undefined : Number(block.getFieldValue('sy')), + 'ir': this.input_to_json(block, 'ir'), + 'is': this.input_to_json(block, 'is') + }; +} +lottie_pucker_bloat(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'a': this.input_to_json(block, 'a') + }; +} +lottie_rectangle(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'd': block.getFieldValue('d') === '' ? undefined : Number(block.getFieldValue('d')), + 'p': this.input_to_json(block, 'p'), + 's': this.input_to_json(block, 's'), + 'r': this.input_to_json(block, 'r') + }; +} +lottie_repeater(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'c': this.input_to_json(block, 'c'), + 'o': this.input_to_json(block, 'o'), + 'm': block.getFieldValue('m') === '' ? undefined : Number(block.getFieldValue('m')), + 'tr': this.input_to_json(block, 'tr') + }; +} +lottie_repeater_transform(block) +{ + return { + 'a': this.input_to_json(block, 'a'), + 's': this.input_to_json(block, 's'), + 'o': this.input_to_json(block, 'o'), + 'sk': this.input_to_json(block, 'sk'), + 'sa': this.input_to_json(block, 'sa'), + 'so': this.input_to_json(block, 'so'), + 'eo': this.input_to_json(block, 'eo') + }; +} +lottie_rounded_corners(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'r': this.input_to_json(block, 'r') + }; +} +lottie_shape_element(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + ...this.object_members_to_json(block, 'custom_attributes') + }; +} +lottie_stroke(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'lc': block.getFieldValue('lc') === '' ? undefined : Number(block.getFieldValue('lc')), + 'lj': block.getFieldValue('lj') === '' ? undefined : Number(block.getFieldValue('lj')), + 'ml': this.input_to_json(block, 'ml'), + 'ml2': this.input_to_json(block, 'ml2'), + 'o': this.input_to_json(block, 'o'), + 'w': this.input_to_json(block, 'w'), + 'd': this.statements_to_json(block, 'd', false), + 'c': this.input_to_json(block, 'c') + }; +} +lottie_stroke_dash(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'n': block.getFieldValue('n') === '' ? undefined : block.getFieldValue('n'), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_transform_shape(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'a': this.input_to_json(block, 'a'), + 'p': this.input_to_json(block, 'p'), + 's': this.input_to_json(block, 's'), + 'o': this.input_to_json(block, 'o'), + 'sk': this.input_to_json(block, 'sk'), + 'sa': this.input_to_json(block, 'sa') + }; +} +lottie_trim(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 's': this.input_to_json(block, 's'), + 'e': this.input_to_json(block, 'e'), + 'o': this.input_to_json(block, 'o'), + 'm': block.getFieldValue('m') === '' ? undefined : Number(block.getFieldValue('m')) + }; +} +lottie_zig_zag(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'hd': 'TRUE' == block.getFieldValue('hd'), + 'ty': block.getFieldValue('ty'), + 'bm': block.getFieldValue('bm') === '' ? undefined : Number(block.getFieldValue('bm')), + 'ix': this.input_to_json(block, 'ix'), + 'cl': this.input_to_json(block, 'cl'), + 'ln': this.input_to_json(block, 'ln'), + 'r': this.input_to_json(block, 'r'), + 's': this.input_to_json(block, 's'), + 'pt': this.input_to_json(block, 'pt') + }; +} +lottie_asset(block) +{ + return { + 'id': block.getFieldValue('id'), + 'nm': this.input_to_json(block, 'nm') + }; +} +lottie_data_source(block) +{ + return { + 'id': block.getFieldValue('id'), + 'nm': this.input_to_json(block, 'nm'), + 'u': this.input_to_json(block, 'u'), + 'p': block.getFieldValue('p'), + 'e': 'TRUE' == block.getFieldValue('e') ? 1 : 0, + 't': Number(block.getFieldValue('t')) + }; +} +lottie_file_asset(block) +{ + return { + 'id': block.getFieldValue('id'), + 'nm': this.input_to_json(block, 'nm'), + 'u': this.input_to_json(block, 'u'), + 'p': block.getFieldValue('p'), + 'e': 'TRUE' == block.getFieldValue('e') ? 1 : 0 + }; +} +lottie_image(block) +{ + return { + 'id': block.getFieldValue('id'), + 'nm': this.input_to_json(block, 'nm'), + 'u': this.input_to_json(block, 'u'), + 'p': block.getFieldValue('p'), + 'e': 'TRUE' == block.getFieldValue('e') ? 1 : 0, + 'w': this.input_to_json(block, 'w'), + 'h': this.input_to_json(block, 'h'), + 't': block.getFieldValue('t'), + 'sid': this.input_to_json(block, 'sid') + }; +} +lottie_precomposition(block) +{ + return { + 'id': block.getFieldValue('id'), + 'nm': this.input_to_json(block, 'nm'), + 'layers': this.statements_to_json(block, 'layers', false), + 'fr': this.input_to_json(block, 'fr'), + 'xt': 'TRUE' == block.getFieldValue('xt') ? 1 : 0 + }; +} +lottie_sound(block) +{ + return { + 'id': block.getFieldValue('id'), + 'nm': this.input_to_json(block, 'nm'), + 'u': this.input_to_json(block, 'u'), + 'p': block.getFieldValue('p'), + 'e': 'TRUE' == block.getFieldValue('e') ? 1 : 0 + }; +} +lottie_displacement_map_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_drop_shadow_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0, + ...this.object_members_to_json(block, 'custom_attributes') + }; +} +lottie_fill_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_gaussian_blur_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_matte3_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_mesh_warp_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_pro_levels_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_puppet_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_radial_wipe_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_spherize_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_stroke_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_tint_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_tritone_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_twirl_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_wavy_effect(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ef': this.statements_to_json(block, 'ef', false), + 'np': this.input_to_json(block, 'np'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'en': 'TRUE' == block.getFieldValue('en') ? 1 : 0 + }; +} +lottie_effect_value_angle(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_checkbox(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_color(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_drop_down(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_effect_value(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': this.input_to_json(block, 'ty') + }; +} +lottie_effect_value_ignored(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_layer(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_no_value(block) +{ + return { + + }; +} +lottie_effect_value_point(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_effect_value_slider(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 'mn': this.input_to_json(block, 'mn'), + 'ix': this.input_to_json(block, 'ix'), + 'ty': Number(block.getFieldValue('ty')), + 'v': this.input_to_json(block, 'v') + }; +} +lottie_animated_text_document(block) +{ + return { + 'k': this.statements_to_json(block, 'k', false), + 'x': this.input_to_json(block, 'x'), + 'sid': this.input_to_json(block, 'sid') + }; +} +lottie_character_data(block) +{ + return { + 'ch': block.getFieldValue('ch'), + 'fFamily': block.getFieldValue('fFamily'), + 'size': Number(block.getFieldValue('size')), + 'style': block.getFieldValue('style'), + 'w': Number(block.getFieldValue('w')) + }; +} +lottie_character_precomp(block) +{ + return { + 'refId': block.getFieldValue('refId'), + 'ks': this.input_to_json(block, 'ks'), + 'ip': this.input_to_json(block, 'ip'), + 'op': this.input_to_json(block, 'op'), + 'sr': this.input_to_json(block, 'sr'), + 'st': this.input_to_json(block, 'st') + }; +} +lottie_character_shapes(block) +{ + return { + 'shapes': this.statements_to_json(block, 'shapes', false) + }; +} +lottie_font(block) +{ + return { + 'ascent': this.input_to_json(block, 'ascent'), + 'fFamily': block.getFieldValue('fFamily'), + 'fName': block.getFieldValue('fName'), + 'fStyle': block.getFieldValue('fStyle'), + 'fPath': this.input_to_json(block, 'fPath'), + 'fWeight': this.input_to_json(block, 'fWeight'), + 'origin': block.getFieldValue('origin') === '' ? undefined : Number(block.getFieldValue('origin')), + 'fClass': this.input_to_json(block, 'fClass') + }; +} +lottie_font_list(block) +{ + return { + 'list': this.statements_to_json(block, 'list', false) + }; +} +lottie_text_alignment_options(block) +{ + return { + 'a': this.input_to_json(block, 'a'), + 'g': block.getFieldValue('g') === '' ? undefined : Number(block.getFieldValue('g')) + }; +} +lottie_text_data(block) +{ + return { + 'a': this.statements_to_json(block, 'a', false), + 'd': this.input_to_json(block, 'd'), + 'm': this.input_to_json(block, 'm'), + 'p': this.input_to_json(block, 'p') + }; +} +lottie_text_document(block) +{ + return { + 'f': block.getFieldValue('f'), + 'fc': this.input_to_json(block, 'fc'), + 'sc': this.input_to_json(block, 'sc'), + 'sw': this.input_to_json(block, 'sw'), + 'of': 'TRUE' == block.getFieldValue('of'), + 's': Number(block.getFieldValue('s')), + 'lh': this.input_to_json(block, 'lh'), + 'sz': this.input_to_json(block, 'sz'), + 'ps': this.input_to_json(block, 'ps'), + 't': block.getFieldValue('t'), + 'j': block.getFieldValue('j') === '' ? undefined : Number(block.getFieldValue('j')), + 'ca': block.getFieldValue('ca') === '' ? undefined : Number(block.getFieldValue('ca')), + 'tr': this.input_to_json(block, 'tr'), + 'ls': this.input_to_json(block, 'ls') + }; +} +lottie_text_document_keyframe(block) +{ + return { + 's': this.input_to_json(block, 's'), + 't': Number(block.getFieldValue('t')) + }; +} +lottie_text_follow_path(block) +{ + return { + 'm': this.input_to_json(block, 'm'), + 'f': this.input_to_json(block, 'f'), + 'l': this.input_to_json(block, 'l'), + 'r': this.input_to_json(block, 'r'), + 'a': this.input_to_json(block, 'a'), + 'p': this.input_to_json(block, 'p') + }; +} +lottie_text_range(block) +{ + return { + 'nm': this.input_to_json(block, 'nm'), + 's': this.input_to_json(block, 's'), + 'a': this.input_to_json(block, 'a') + }; +} +lottie_text_range_selector(block) +{ + return { + 't': 'TRUE' == block.getFieldValue('t') ? 1 : 0, + 'xe': this.input_to_json(block, 'xe'), + 'ne': this.input_to_json(block, 'ne'), + 'a': this.input_to_json(block, 'a'), + 'b': block.getFieldValue('b') === '' ? undefined : Number(block.getFieldValue('b')), + 'rn': 'TRUE' == block.getFieldValue('rn') ? 1 : 0, + 'sh': block.getFieldValue('sh') === '' ? undefined : Number(block.getFieldValue('sh')), + 'o': this.input_to_json(block, 'o'), + 'r': block.getFieldValue('r') === '' ? undefined : Number(block.getFieldValue('r')), + 'sm': this.input_to_json(block, 'sm'), + 's': this.input_to_json(block, 's'), + 'e': this.input_to_json(block, 'e') + }; +} +lottie_text_style(block) +{ + return { + 'a': this.input_to_json(block, 'a'), + 's': this.input_to_json(block, 's'), + 'o': this.input_to_json(block, 'o'), + 'sk': this.input_to_json(block, 'sk'), + 'sa': this.input_to_json(block, 'sa'), + 'sw': this.input_to_json(block, 'sw'), + 'sc': this.input_to_json(block, 'sc'), + 'sh': this.input_to_json(block, 'sh'), + 'ss': this.input_to_json(block, 'ss'), + 'sb': this.input_to_json(block, 'sb'), + 'so': this.input_to_json(block, 'so'), + 'fc': this.input_to_json(block, 'fc'), + 'fh': this.input_to_json(block, 'fh'), + 'fs': this.input_to_json(block, 'fs'), + 'fb': this.input_to_json(block, 'fb'), + 'fo': this.input_to_json(block, 'fo'), + 't': this.input_to_json(block, 't'), + 'bl': this.input_to_json(block, 'bl'), + 'ls': this.input_to_json(block, 'ls') + }; +} +} +class GeneratedParser { +lottie_animation(parent, json) +{ + var block = this.create_block(parent, 'lottie_animation'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.v !== undefined ) this.create_value_block(this.value(block, "v"), json.v, ""); + if ( json.fr !== undefined ) this.set_field(block, "fr", json.fr.toString()); + if ( json.ip !== undefined ) this.set_field(block, "ip", json.ip.toString()); + if ( json.op !== undefined ) this.set_field(block, "op", json.op.toString()); + if ( json.w !== undefined ) this.set_field(block, "w", json.w.toString()); + if ( json.h !== undefined ) this.set_field(block, "h", json.h.toString()); + if ( json.ddd !== undefined ) this.set_field(block, "ddd", json.ddd ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.assets) ) this.statements_from_json(block, 'assets', json.assets, 'assets'); + if ( Array.isArray(json.comps) ) this.statements_from_json(block, 'comps', json.comps, 'lottie_precomposition'); + if ( json.fonts !== undefined ) this.lottie_font_list(this.value(block, "fonts"), json.fonts); + if ( Array.isArray(json.chars) ) this.statements_from_json(block, 'chars', json.chars, 'lottie_character_data'); + if ( json.meta !== undefined ) this.lottie_metadata(this.value(block, "meta"), json.meta); + if ( json.metadata !== undefined ) this.lottie_user_metadata(this.value(block, "metadata"), json.metadata); + if ( Array.isArray(json.markers) ) this.statements_from_json(block, 'markers', json.markers, ''); + if ( json.mb !== undefined ) this.lottie_motion_blur(this.value(block, "mb"), json.mb); + if ( json.slots !== undefined ) this.create_value_block(this.value(block, "slots"), json.slots, ""); + if ( Array.isArray(json.layers) ) this.statements_from_json(block, 'layers', json.layers, 'layers') + return block; +} +lottie_metadata(parent, json) +{ + var block = this.create_block(parent, 'lottie_metadata'); + if ( json.a !== undefined ) this.create_value_block(this.value(block, "a"), json.a, ""); + if ( json.d !== undefined ) this.create_value_block(this.value(block, "d"), json.d, ""); + if ( json.tc !== undefined ) this.create_value_block(this.value(block, "tc"), json.tc, ""); + if ( json.g !== undefined ) this.create_value_block(this.value(block, "g"), json.g, "") + return block; +} +lottie_motion_blur(parent, json) +{ + var block = this.create_block(parent, 'lottie_motion_blur'); + if ( json.sa !== undefined ) this.create_value_block(this.value(block, "sa"), json.sa, ""); + if ( json.sp !== undefined ) this.create_value_block(this.value(block, "sp"), json.sp, ""); + if ( json.spf !== undefined ) this.create_value_block(this.value(block, "spf"), json.spf, ""); + if ( json.asl !== undefined ) this.create_value_block(this.value(block, "asl"), json.asl, "") + return block; +} +lottie_user_metadata(parent, json) +{ + var block = this.create_block(parent, 'lottie_user_metadata'); + if ( json.filename !== undefined ) this.create_value_block(this.value(block, "filename"), json.filename, ""); + if ( json.customProps !== undefined ) this.create_value_block(this.value(block, "customProps"), json.customProps, "") + return block; +} +lottie_layer_common(parent, json) +{ + var block = this.create_block(parent, 'lottie_layer_common'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ddd !== undefined ) this.set_field(block, "ddd", json.ddd ? 'TRUE' : 'FALSE'); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ind !== undefined ) this.create_value_block(this.value(block, "ind"), json.ind, ""); + if ( json.parent !== undefined ) this.create_value_block(this.value(block, "parent"), json.parent, ""); + if ( json.sr !== undefined ) this.create_value_block(this.value(block, "sr"), json.sr, ""); + if ( json.ip !== undefined ) this.set_field(block, "ip", json.ip.toString()); + if ( json.op !== undefined ) this.set_field(block, "op", json.op.toString()); + if ( json.st !== undefined ) this.set_field(block, "st", json.st.toString()) + return block; +} +lottie_audio_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_audio_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.au !== undefined ) this.lottie_audio_settings(this.value(block, "au"), json.au); + if ( json.refId !== undefined ) this.create_value_block(this.value(block, "refId"), json.refId, "") + return block; +} +lottie_audio_settings(parent, json) +{ + var block = this.create_block(parent, 'lottie_audio_settings'); + this.create_property_block(block, json, "lv", "vector") + return block; +} +lottie_camera_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_camera_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + this.create_property_block(block, json, "pe", "") + return block; +} +lottie_data_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_data_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.refId !== undefined ) this.create_value_block(this.value(block, "refId"), json.refId, "") + return block; +} +lottie_image_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_image_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.refId !== undefined ) this.set_field(block, "refId", json.refId) + return block; +} +lottie_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.object_members_from_json(block, json, "custom_attributes") + return block; +} +lottie_null_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_null_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()) + return block; +} +lottie_precomposition_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_precomposition_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.refId !== undefined ) this.set_field(block, "refId", json.refId); + if ( json.w !== undefined ) this.set_field(block, "w", json.w.toString()); + if ( json.h !== undefined ) this.set_field(block, "h", json.h.toString()); + this.create_property_block(block, json, "tm", "") + return block; +} +lottie_shape_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_shape_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( Array.isArray(json.shapes) ) this.statements_from_json(block, 'shapes', json.shapes, 'shapes') + return block; +} +lottie_solid_color_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_solid_color_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.sc !== undefined ) this.set_field(block, "sc", json.sc); + if ( json.sh !== undefined ) this.set_field(block, "sh", json.sh.toString()); + if ( json.sw !== undefined ) this.set_field(block, "sw", json.sw.toString()) + return block; +} +lottie_text_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.t !== undefined ) this.lottie_text_data(this.value(block, "t"), json.t) + return block; +} +lottie_visual_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_visual_layer'); + this.json_to_block(this.value(block, 'lottie_layer_common'), json, 'lottie_layer_common', BlocklyJsonParser.Output); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ao !== undefined ) this.set_field(block, "ao", json.ao ? 'TRUE' : 'FALSE'); + if ( json.tt !== undefined ) this.set_field(block, "tt", json.tt.toString()); + if ( json.tp !== undefined ) this.create_value_block(this.value(block, "tp"), json.tp, ""); + if ( json.td !== undefined ) this.set_field(block, "td", json.td ? 'TRUE' : 'FALSE'); + if ( json.hasMask !== undefined ) this.set_field(block, "hasMask", json.hasMask ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.masksProperties) ) this.statements_from_json(block, 'masksProperties', json.masksProperties, ''); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effects'); + if ( json.mb !== undefined ) this.set_field(block, "mb", json.mb ? 'TRUE' : 'FALSE'); + if ( Array.isArray(json.sy) ) this.statements_from_json(block, 'sy', json.sy, 'styles'); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.tg !== undefined ) this.create_value_block(this.value(block, "tg"), json.tg, ""); + if ( json.cp !== undefined ) this.set_field(block, "cp", json.cp ? 'TRUE' : 'FALSE'); + if ( json.ct !== undefined ) this.set_field(block, "ct", json.ct ? 'TRUE' : 'FALSE') + return block; +} +lottie_ellipse(parent, json) +{ + var block = this.create_block(parent, 'lottie_ellipse'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.d !== undefined ) this.set_field(block, "d", json.d.toString()); + this.maybe_split_property(block, json, "p"); + this.create_property_block(block, json, "s", "vector") + return block; +} +lottie_fill(parent, json) +{ + var block = this.create_block(parent, 'lottie_fill'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "o", ""); + this.create_property_block(block, json, "c", "color"); + if ( json.r !== undefined ) this.set_field(block, "r", json.r.toString()) + return block; +} +lottie_gradient_fill(parent, json) +{ + var block = this.create_block(parent, 'lottie_gradient_fill'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "s", "vector"); + this.create_property_block(block, json, "e", "vector"); + if ( json.t !== undefined ) this.set_field(block, "t", json.t.toString()); + this.create_property_block(block, json, "h", ""); + this.create_property_block(block, json, "a", ""); + if ( json.g !== undefined ) this.lottie_gradient_colors(this.value(block, "g"), json.g); + this.create_property_block(block, json, "o", ""); + if ( json.r !== undefined ) this.set_field(block, "r", json.r.toString()) + return block; +} +lottie_gradient_stroke(parent, json) +{ + var block = this.create_block(parent, 'lottie_gradient_stroke'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.lc !== undefined ) this.set_field(block, "lc", json.lc.toString()); + if ( json.lj !== undefined ) this.set_field(block, "lj", json.lj.toString()); + if ( json.ml !== undefined ) this.create_value_block(this.value(block, "ml"), json.ml, ""); + this.create_property_block(block, json, "ml2", ""); + this.create_property_block(block, json, "o", ""); + this.create_property_block(block, json, "w", ""); + if ( Array.isArray(json.d) ) this.statements_from_json(block, 'd', json.d, 'lottie_stroke_dash'); + this.create_property_block(block, json, "s", "vector"); + this.create_property_block(block, json, "e", "vector"); + if ( json.t !== undefined ) this.set_field(block, "t", json.t.toString()); + this.create_property_block(block, json, "h", ""); + this.create_property_block(block, json, "a", ""); + if ( json.g !== undefined ) this.lottie_gradient_colors(this.value(block, "g"), json.g) + return block; +} +lottie_group(parent, json) +{ + var block = this.create_block(parent, 'lottie_group'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( Array.isArray(json.it) ) this.statements_from_json(block, 'it', json.it, 'shapes'); + if ( json.cix !== undefined ) this.create_value_block(this.value(block, "cix"), json.cix, "") + return block; +} +lottie_no_style(parent, json) +{ + var block = this.create_block(parent, 'lottie_no_style'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, "") + return block; +} +lottie_path(parent, json) +{ + var block = this.create_block(parent, 'lottie_path'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.d !== undefined ) this.set_field(block, "d", json.d.toString()); + this.create_property_block(block, json, "ks", "") + return block; +} +lottie_polystar(parent, json) +{ + var block = this.create_block(parent, 'lottie_polystar'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.d !== undefined ) this.set_field(block, "d", json.d.toString()); + this.maybe_split_property(block, json, "p"); + this.create_property_block(block, json, "or", ""); + this.create_property_block(block, json, "os", ""); + this.create_property_block(block, json, "r", "angle"); + this.create_property_block(block, json, "pt", ""); + if ( json.sy !== undefined ) this.set_field(block, "sy", json.sy.toString()); + this.create_property_block(block, json, "ir", ""); + this.create_property_block(block, json, "is", "") + return block; +} +lottie_pucker_bloat(parent, json) +{ + var block = this.create_block(parent, 'lottie_pucker_bloat'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "a", "") + return block; +} +lottie_rectangle(parent, json) +{ + var block = this.create_block(parent, 'lottie_rectangle'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.d !== undefined ) this.set_field(block, "d", json.d.toString()); + this.maybe_split_property(block, json, "p"); + this.create_property_block(block, json, "s", "vector"); + this.create_property_block(block, json, "r", "") + return block; +} +lottie_repeater(parent, json) +{ + var block = this.create_block(parent, 'lottie_repeater'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "c", ""); + this.create_property_block(block, json, "o", ""); + if ( json.m !== undefined ) this.set_field(block, "m", json.m.toString()); + if ( json.tr !== undefined ) this.lottie_repeater_transform(this.value(block, "tr"), json.tr) + return block; +} +lottie_repeater_transform(parent, json) +{ + var block = this.create_block(parent, 'lottie_repeater_transform'); + this.create_property_block(block, json, "a", "vector"); + this.create_property_block(block, json, "s", "vector"); + this.create_property_block(block, json, "o", ""); + this.create_property_block(block, json, "sk", ""); + this.create_property_block(block, json, "sa", ""); + this.create_property_block(block, json, "so", ""); + this.create_property_block(block, json, "eo", "") + return block; +} +lottie_rounded_corners(parent, json) +{ + var block = this.create_block(parent, 'lottie_rounded_corners'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "r", "") + return block; +} +lottie_shape_element(parent, json) +{ + var block = this.create_block(parent, 'lottie_shape_element'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.object_members_from_json(block, json, "custom_attributes") + return block; +} +lottie_stroke(parent, json) +{ + var block = this.create_block(parent, 'lottie_stroke'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + if ( json.lc !== undefined ) this.set_field(block, "lc", json.lc.toString()); + if ( json.lj !== undefined ) this.set_field(block, "lj", json.lj.toString()); + if ( json.ml !== undefined ) this.create_value_block(this.value(block, "ml"), json.ml, ""); + this.create_property_block(block, json, "ml2", ""); + this.create_property_block(block, json, "o", ""); + this.create_property_block(block, json, "w", ""); + if ( Array.isArray(json.d) ) this.statements_from_json(block, 'd', json.d, 'lottie_stroke_dash'); + this.create_property_block(block, json, "c", "color") + return block; +} +lottie_stroke_dash(parent, json) +{ + var block = this.create_block(parent, 'lottie_stroke_dash'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.n !== undefined ) this.set_field(block, "n", json.n); + this.create_property_block(block, json, "v", "") + return block; +} +lottie_transform_shape(parent, json) +{ + var block = this.create_block(parent, 'lottie_transform_shape'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "a", "vector"); + this.maybe_split_property(block, json, "p"); + this.create_property_block(block, json, "s", "vector"); + this.create_property_block(block, json, "o", ""); + this.create_property_block(block, json, "sk", ""); + this.create_property_block(block, json, "sa", "") + return block; +} +lottie_trim(parent, json) +{ + var block = this.create_block(parent, 'lottie_trim'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "s", ""); + this.create_property_block(block, json, "e", ""); + this.create_property_block(block, json, "o", ""); + if ( json.m !== undefined ) this.set_field(block, "m", json.m.toString()) + return block; +} +lottie_zig_zag(parent, json) +{ + var block = this.create_block(parent, 'lottie_zig_zag'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.hd !== undefined ) this.set_field(block, "hd", json.hd ? 'TRUE' : 'FALSE'); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty); + if ( json.bm !== undefined ) this.set_field(block, "bm", json.bm.toString()); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.cl !== undefined ) this.create_value_block(this.value(block, "cl"), json.cl, ""); + if ( json.ln !== undefined ) this.create_value_block(this.value(block, "ln"), json.ln, ""); + this.create_property_block(block, json, "r", ""); + this.create_property_block(block, json, "s", ""); + this.create_property_block(block, json, "pt", "") + return block; +} +lottie_asset(parent, json) +{ + var block = this.create_block(parent, 'lottie_asset'); + if ( json.id !== undefined ) this.set_field(block, "id", json.id); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, "") + return block; +} +lottie_data_source(parent, json) +{ + var block = this.create_block(parent, 'lottie_data_source'); + if ( json.id !== undefined ) this.set_field(block, "id", json.id); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.u !== undefined ) this.create_value_block(this.value(block, "u"), json.u, ""); + if ( json.p !== undefined ) this.set_field(block, "p", json.p); + if ( json.e !== undefined ) this.set_field(block, "e", json.e ? 'TRUE' : 'FALSE'); + if ( json.t !== undefined ) this.set_field(block, "t", json.t.toString()) + return block; +} +lottie_file_asset(parent, json) +{ + var block = this.create_block(parent, 'lottie_file_asset'); + if ( json.id !== undefined ) this.set_field(block, "id", json.id); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.u !== undefined ) this.create_value_block(this.value(block, "u"), json.u, ""); + if ( json.p !== undefined ) this.set_field(block, "p", json.p); + if ( json.e !== undefined ) this.set_field(block, "e", json.e ? 'TRUE' : 'FALSE') + return block; +} +lottie_image(parent, json) +{ + var block = this.create_block(parent, 'lottie_image'); + if ( json.id !== undefined ) this.set_field(block, "id", json.id); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.u !== undefined ) this.create_value_block(this.value(block, "u"), json.u, ""); + if ( json.p !== undefined ) this.set_field(block, "p", json.p); + if ( json.e !== undefined ) this.set_field(block, "e", json.e ? 'TRUE' : 'FALSE'); + if ( json.w !== undefined ) this.create_value_block(this.value(block, "w"), json.w, ""); + if ( json.h !== undefined ) this.create_value_block(this.value(block, "h"), json.h, ""); + if ( json.t !== undefined ) this.set_field(block, "t", json.t); + if ( json.sid !== undefined ) this.create_value_block(this.value(block, "sid"), json.sid, "") + return block; +} +lottie_precomposition(parent, json) +{ + var block = this.create_block(parent, 'lottie_precomposition'); + if ( json.id !== undefined ) this.set_field(block, "id", json.id); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( Array.isArray(json.layers) ) this.statements_from_json(block, 'layers', json.layers, 'layers'); + if ( json.fr !== undefined ) this.create_value_block(this.value(block, "fr"), json.fr, ""); + if ( json.xt !== undefined ) this.set_field(block, "xt", json.xt ? 'TRUE' : 'FALSE') + return block; +} +lottie_sound(parent, json) +{ + var block = this.create_block(parent, 'lottie_sound'); + if ( json.id !== undefined ) this.set_field(block, "id", json.id); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.u !== undefined ) this.create_value_block(this.value(block, "u"), json.u, ""); + if ( json.p !== undefined ) this.set_field(block, "p", json.p); + if ( json.e !== undefined ) this.set_field(block, "e", json.e ? 'TRUE' : 'FALSE') + return block; +} +lottie_displacement_map_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_displacement_map_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_drop_shadow_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_drop_shadow_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, 'effect_values'); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE'); + this.object_members_from_json(block, json, "custom_attributes") + return block; +} +lottie_fill_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_fill_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_gaussian_blur_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_gaussian_blur_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_matte3_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_matte3_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_mesh_warp_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_mesh_warp_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_pro_levels_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_pro_levels_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_puppet_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_puppet_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_radial_wipe_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_radial_wipe_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_spherize_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_spherize_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_stroke_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_stroke_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_tint_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_tint_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_tritone_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_tritone_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_twirl_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_twirl_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_wavy_effect(parent, json) +{ + var block = this.create_block(parent, 'lottie_wavy_effect'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( Array.isArray(json.ef) ) this.statements_from_json(block, 'ef', json.ef, ''); + if ( json.np !== undefined ) this.create_value_block(this.value(block, "np"), json.np, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.en !== undefined ) this.set_field(block, "en", json.en ? 'TRUE' : 'FALSE') + return block; +} +lottie_effect_value_angle(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_angle'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "") + return block; +} +lottie_effect_value_checkbox(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_checkbox'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "") + return block; +} +lottie_effect_value_color(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_color'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "color") + return block; +} +lottie_effect_value_drop_down(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_drop_down'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "") + return block; +} +lottie_effect_value_effect_value(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_effect_value'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.create_value_block(this.value(block, "ty"), json.ty, "") + return block; +} +lottie_effect_value_ignored(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_ignored'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + if ( json.v !== undefined ) this.create_value_block(this.value(block, "v"), json.v, "") + return block; +} +lottie_effect_value_layer(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_layer'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "") + return block; +} +lottie_effect_value_no_value(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_no_value'); + + return block; +} +lottie_effect_value_point(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_point'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "vector") + return block; +} +lottie_effect_value_slider(parent, json) +{ + var block = this.create_block(parent, 'lottie_effect_value_slider'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.mn !== undefined ) this.create_value_block(this.value(block, "mn"), json.mn, ""); + if ( json.ix !== undefined ) this.create_value_block(this.value(block, "ix"), json.ix, ""); + if ( json.ty !== undefined ) this.set_field(block, "ty", json.ty.toString()); + this.create_property_block(block, json, "v", "") + return block; +} +lottie_animated_text_document(parent, json) +{ + var block = this.create_block(parent, 'lottie_animated_text_document'); + if ( Array.isArray(json.k) ) this.statements_from_json(block, 'k', json.k, 'lottie_text_document_keyframe'); + if ( json.x !== undefined ) this.create_value_block(this.value(block, "x"), json.x, ""); + if ( json.sid !== undefined ) this.create_value_block(this.value(block, "sid"), json.sid, "") + return block; +} +lottie_character_data(parent, json) +{ + var block = this.create_block(parent, 'lottie_character_data'); + if ( json.ch !== undefined ) this.set_field(block, "ch", json.ch); + if ( json.fFamily !== undefined ) this.set_field(block, "fFamily", json.fFamily); + if ( json.size !== undefined ) this.set_field(block, "size", json.size.toString()); + if ( json.style !== undefined ) this.set_field(block, "style", json.style); + if ( json.w !== undefined ) this.set_field(block, "w", json.w.toString()) + return block; +} +lottie_character_precomp(parent, json) +{ + var block = this.create_block(parent, 'lottie_character_precomp'); + if ( json.refId !== undefined ) this.set_field(block, "refId", json.refId); + if ( json.ks !== undefined ) this.lottie_transform(this.value(block, "ks"), json.ks); + if ( json.ip !== undefined ) this.create_value_block(this.value(block, "ip"), json.ip, ""); + if ( json.op !== undefined ) this.create_value_block(this.value(block, "op"), json.op, ""); + if ( json.sr !== undefined ) this.create_value_block(this.value(block, "sr"), json.sr, ""); + if ( json.st !== undefined ) this.create_value_block(this.value(block, "st"), json.st, "") + return block; +} +lottie_character_shapes(parent, json) +{ + var block = this.create_block(parent, 'lottie_character_shapes'); + if ( Array.isArray(json.shapes) ) this.statements_from_json(block, 'shapes', json.shapes, 'shapes') + return block; +} +lottie_font(parent, json) +{ + var block = this.create_block(parent, 'lottie_font'); + if ( json.ascent !== undefined ) this.create_value_block(this.value(block, "ascent"), json.ascent, ""); + if ( json.fFamily !== undefined ) this.set_field(block, "fFamily", json.fFamily); + if ( json.fName !== undefined ) this.set_field(block, "fName", json.fName); + if ( json.fStyle !== undefined ) this.set_field(block, "fStyle", json.fStyle); + if ( json.fPath !== undefined ) this.create_value_block(this.value(block, "fPath"), json.fPath, ""); + if ( json.fWeight !== undefined ) this.create_value_block(this.value(block, "fWeight"), json.fWeight, ""); + if ( json.origin !== undefined ) this.set_field(block, "origin", json.origin.toString()); + if ( json.fClass !== undefined ) this.create_value_block(this.value(block, "fClass"), json.fClass, "") + return block; +} +lottie_font_list(parent, json) +{ + var block = this.create_block(parent, 'lottie_font_list'); + if ( Array.isArray(json.list) ) this.statements_from_json(block, 'list', json.list, 'lottie_font') + return block; +} +lottie_text_alignment_options(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_alignment_options'); + this.create_property_block(block, json, "a", "vector"); + if ( json.g !== undefined ) this.set_field(block, "g", json.g.toString()) + return block; +} +lottie_text_data(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_data'); + if ( Array.isArray(json.a) ) this.statements_from_json(block, 'a', json.a, 'lottie_text_range'); + if ( json.d !== undefined ) this.lottie_animated_text_document(this.value(block, "d"), json.d); + if ( json.m !== undefined ) this.lottie_text_alignment_options(this.value(block, "m"), json.m); + this.maybe_split_property(block, json, "p") + return block; +} +lottie_text_document(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_document'); + if ( json.f !== undefined ) this.set_field(block, "f", json.f); + if ( json.fc !== undefined ) this.create_value_block(this.value(block, "fc"), json.fc, ""); + if ( json.sc !== undefined ) this.create_value_block(this.value(block, "sc"), json.sc, ""); + if ( json.sw !== undefined ) this.create_value_block(this.value(block, "sw"), json.sw, ""); + if ( json.of !== undefined ) this.set_field(block, "of", json.of ? 'TRUE' : 'FALSE'); + if ( json.s !== undefined ) this.set_field(block, "s", json.s.toString()); + if ( json.lh !== undefined ) this.create_value_block(this.value(block, "lh"), json.lh, ""); + if ( json.sz !== undefined ) this.create_value_block(this.value(block, "sz"), json.sz, ""); + if ( json.ps !== undefined ) this.create_value_block(this.value(block, "ps"), json.ps, ""); + if ( json.t !== undefined ) this.set_field(block, "t", json.t); + if ( json.j !== undefined ) this.set_field(block, "j", json.j.toString()); + if ( json.ca !== undefined ) this.set_field(block, "ca", json.ca.toString()); + if ( json.tr !== undefined ) this.create_value_block(this.value(block, "tr"), json.tr, ""); + if ( json.ls !== undefined ) this.create_value_block(this.value(block, "ls"), json.ls, "") + return block; +} +lottie_text_document_keyframe(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_document_keyframe'); + if ( json.s !== undefined ) this.lottie_text_document(this.value(block, "s"), json.s); + if ( json.t !== undefined ) this.set_field(block, "t", json.t.toString()) + return block; +} +lottie_text_follow_path(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_follow_path'); + if ( json.m !== undefined ) this.create_value_block(this.value(block, "m"), json.m, ""); + this.create_property_block(block, json, "f", ""); + this.create_property_block(block, json, "l", ""); + this.create_property_block(block, json, "r", ""); + this.create_property_block(block, json, "a", ""); + this.maybe_split_property(block, json, "p") + return block; +} +lottie_text_range(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_range'); + if ( json.nm !== undefined ) this.create_value_block(this.value(block, "nm"), json.nm, ""); + if ( json.s !== undefined ) this.lottie_text_range_selector(this.value(block, "s"), json.s); + if ( json.a !== undefined ) this.lottie_text_style(this.value(block, "a"), json.a) + return block; +} +lottie_text_range_selector(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_range_selector'); + if ( json.t !== undefined ) this.set_field(block, "t", json.t ? 'TRUE' : 'FALSE'); + this.create_property_block(block, json, "xe", ""); + this.create_property_block(block, json, "ne", ""); + this.create_property_block(block, json, "a", ""); + if ( json.b !== undefined ) this.set_field(block, "b", json.b.toString()); + if ( json.rn !== undefined ) this.set_field(block, "rn", json.rn ? 'TRUE' : 'FALSE'); + if ( json.sh !== undefined ) this.set_field(block, "sh", json.sh.toString()); + this.create_property_block(block, json, "o", ""); + if ( json.r !== undefined ) this.set_field(block, "r", json.r.toString()); + this.create_property_block(block, json, "sm", ""); + this.create_property_block(block, json, "s", ""); + this.create_property_block(block, json, "e", "") + return block; +} +lottie_text_style(parent, json) +{ + var block = this.create_block(parent, 'lottie_text_style'); + this.create_property_block(block, json, "a", "vector"); + this.create_property_block(block, json, "s", "vector"); + this.create_property_block(block, json, "o", ""); + this.create_property_block(block, json, "sk", ""); + this.create_property_block(block, json, "sa", ""); + this.create_property_block(block, json, "sw", ""); + this.create_property_block(block, json, "sc", "color"); + this.create_property_block(block, json, "sh", ""); + this.create_property_block(block, json, "ss", ""); + this.create_property_block(block, json, "sb", ""); + this.create_property_block(block, json, "so", ""); + this.create_property_block(block, json, "fc", "color"); + this.create_property_block(block, json, "fh", ""); + this.create_property_block(block, json, "fs", ""); + this.create_property_block(block, json, "fb", ""); + this.create_property_block(block, json, "fo", ""); + this.create_property_block(block, json, "t", ""); + this.create_property_block(block, json, "bl", ""); + this.create_property_block(block, json, "ls", "") + return block; +} +get_type_for_layers(json){ + switch ( json.ty ) { + case 0: return 'lottie_precomposition_layer'; + case 1: return 'lottie_solid_color_layer'; + case 2: return 'lottie_image_layer'; + case 3: return 'lottie_null_layer'; + case 4: return 'lottie_shape_layer'; + case 5: return 'lottie_text_layer'; + case 6: return 'lottie_audio_layer'; + case 13: return 'lottie_camera_layer'; + case 15: return 'lottie_data_layer'; + default: return ''; + } +} +get_type_for_shapes(json){ + switch ( json.ty ) { + case 'el': return 'lottie_ellipse'; + case 'fl': return 'lottie_fill'; + case 'gf': return 'lottie_gradient_fill'; + case 'gr': return 'lottie_group'; + case 'gs': return 'lottie_gradient_stroke'; + case 'no': return 'lottie_no_style'; + case 'pb': return 'lottie_pucker_bloat'; + case 'rc': return 'lottie_rectangle'; + case 'rd': return 'lottie_rounded_corners'; + case 'rp': return 'lottie_repeater'; + case 'sh': return 'lottie_path'; + case 'sr': return 'lottie_polystar'; + case 'st': return 'lottie_stroke'; + case 'tm': return 'lottie_trim'; + case 'tr': return 'lottie_transform_shape'; + case 'zz': return 'lottie_zig_zag'; + default: return ''; + } +} +get_type_for_effects(json){ + switch ( json.ty ) { + case 20: return 'lottie_tint_effect'; + case 21: return 'lottie_fill_effect'; + case 22: return 'lottie_stroke_effect'; + case 23: return 'lottie_tritone_effect'; + case 24: return 'lottie_pro_levels_effect'; + case 25: return 'lottie_drop_shadow_effect'; + case 26: return 'lottie_radial_wipe_effect'; + case 27: return 'lottie_displacement_map_effect'; + case 28: return 'lottie_matte3_effect'; + case 29: return 'lottie_gaussian_blur_effect'; + case 30: return 'lottie_twirl_effect'; + case 31: return 'lottie_mesh_warp_effect'; + case 32: return 'lottie_wavy_effect'; + case 33: return 'lottie_spherize_effect'; + case 34: return 'lottie_puppet_effect'; + default: return ''; + } +} +get_type_for_effect_values(json){ + switch ( json.ty ) { + case 0: return 'lottie_effect_value_slider'; + case 1: return 'lottie_effect_value_angle'; + case 2: return 'lottie_effect_value_color'; + case 3: return 'lottie_effect_value_point'; + case 4: return 'lottie_effect_value_checkbox'; + case 6: return 'lottie_effect_value_ignored'; + case 7: return 'lottie_effect_value_drop_down'; + case 10: return 'lottie_effect_value_layer'; + default: return ''; + } +} +} diff --git a/scripts/editor.bundle.js b/scripts/editor.bundle.js new file mode 100644 index 00000000..627e0dea --- /dev/null +++ b/scripts/editor.bundle.js @@ -0,0 +1,23827 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CodeMirrorWrapper = {})); +})(this, (function (exports) { 'use strict'; + + /** + The data structure for documents. @nonabstract + */ + class Text { + /** + @internal + */ + constructor() { } + /** + Get the line description around the given position. + */ + lineAt(pos) { + if (pos < 0 || pos > this.length) + throw new RangeError(`Invalid position ${pos} in document of length ${this.length}`); + return this.lineInner(pos, false, 1, 0); + } + /** + Get the description for the given (1-based) line number. + */ + line(n) { + if (n < 1 || n > this.lines) + throw new RangeError(`Invalid line number ${n} in ${this.lines}-line document`); + return this.lineInner(n, true, 1, 0); + } + /** + Replace a range of the text with the given content. + */ + replace(from, to, text) { + let parts = []; + this.decompose(0, from, parts, 2 /* To */); + if (text.length) + text.decompose(0, text.length, parts, 1 /* From */ | 2 /* To */); + this.decompose(to, this.length, parts, 1 /* From */); + return TextNode.from(parts, this.length - (to - from) + text.length); + } + /** + Append another document to this one. + */ + append(other) { + return this.replace(this.length, this.length, other); + } + /** + Retrieve the text between the given points. + */ + slice(from, to = this.length) { + let parts = []; + this.decompose(from, to, parts, 0); + return TextNode.from(parts, to - from); + } + /** + Test whether this text is equal to another instance. + */ + eq(other) { + if (other == this) + return true; + if (other.length != this.length || other.lines != this.lines) + return false; + let start = this.scanIdentical(other, 1), end = this.length - this.scanIdentical(other, -1); + let a = new RawTextCursor(this), b = new RawTextCursor(other); + for (let skip = start, pos = start;;) { + a.next(skip); + b.next(skip); + skip = 0; + if (a.lineBreak != b.lineBreak || a.done != b.done || a.value != b.value) + return false; + pos += a.value.length; + if (a.done || pos >= end) + return true; + } + } + /** + Iterate over the text. When `dir` is `-1`, iteration happens + from end to start. This will return lines and the breaks between + them as separate strings. + */ + iter(dir = 1) { return new RawTextCursor(this, dir); } + /** + Iterate over a range of the text. When `from` > `to`, the + iterator will run in reverse. + */ + iterRange(from, to = this.length) { return new PartialTextCursor(this, from, to); } + /** + Return a cursor that iterates over the given range of lines, + _without_ returning the line breaks between, and yielding empty + strings for empty lines. + + When `from` and `to` are given, they should be 1-based line numbers. + */ + iterLines(from, to) { + let inner; + if (from == null) { + inner = this.iter(); + } + else { + if (to == null) + to = this.lines + 1; + let start = this.line(from).from; + inner = this.iterRange(start, Math.max(start, to == this.lines + 1 ? this.length : to <= 1 ? 0 : this.line(to - 1).to)); + } + return new LineCursor(inner); + } + /** + @internal + */ + toString() { return this.sliceString(0); } + /** + Convert the document to an array of lines (which can be + deserialized again via [`Text.of`](https://codemirror.net/6/docs/ref/#state.Text^of)). + */ + toJSON() { + let lines = []; + this.flatten(lines); + return lines; + } + /** + Create a `Text` instance for the given array of lines. + */ + static of(text) { + if (text.length == 0) + throw new RangeError("A document must have at least one line"); + if (text.length == 1 && !text[0]) + return Text.empty; + return text.length <= 32 /* Branch */ ? new TextLeaf(text) : TextNode.from(TextLeaf.split(text, [])); + } + } + // Leaves store an array of line strings. There are always line breaks + // between these strings. Leaves are limited in size and have to be + // contained in TextNode instances for bigger documents. + class TextLeaf extends Text { + constructor(text, length = textLength(text)) { + super(); + this.text = text; + this.length = length; + } + get lines() { return this.text.length; } + get children() { return null; } + lineInner(target, isLine, line, offset) { + for (let i = 0;; i++) { + let string = this.text[i], end = offset + string.length; + if ((isLine ? line : end) >= target) + return new Line(offset, end, line, string); + offset = end + 1; + line++; + } + } + decompose(from, to, target, open) { + let text = from <= 0 && to >= this.length ? this + : new TextLeaf(sliceText(this.text, from, to), Math.min(to, this.length) - Math.max(0, from)); + if (open & 1 /* From */) { + let prev = target.pop(); + let joined = appendText(text.text, prev.text.slice(), 0, text.length); + if (joined.length <= 32 /* Branch */) { + target.push(new TextLeaf(joined, prev.length + text.length)); + } + else { + let mid = joined.length >> 1; + target.push(new TextLeaf(joined.slice(0, mid)), new TextLeaf(joined.slice(mid))); + } + } + else { + target.push(text); + } + } + replace(from, to, text) { + if (!(text instanceof TextLeaf)) + return super.replace(from, to, text); + let lines = appendText(this.text, appendText(text.text, sliceText(this.text, 0, from)), to); + let newLen = this.length + text.length - (to - from); + if (lines.length <= 32 /* Branch */) + return new TextLeaf(lines, newLen); + return TextNode.from(TextLeaf.split(lines, []), newLen); + } + sliceString(from, to = this.length, lineSep = "\n") { + let result = ""; + for (let pos = 0, i = 0; pos <= to && i < this.text.length; i++) { + let line = this.text[i], end = pos + line.length; + if (pos > from && i) + result += lineSep; + if (from < end && to > pos) + result += line.slice(Math.max(0, from - pos), to - pos); + pos = end + 1; + } + return result; + } + flatten(target) { + for (let line of this.text) + target.push(line); + } + scanIdentical() { return 0; } + static split(text, target) { + let part = [], len = -1; + for (let line of text) { + part.push(line); + len += line.length + 1; + if (part.length == 32 /* Branch */) { + target.push(new TextLeaf(part, len)); + part = []; + len = -1; + } + } + if (len > -1) + target.push(new TextLeaf(part, len)); + return target; + } + } + // Nodes provide the tree structure of the `Text` type. They store a + // number of other nodes or leaves, taking care to balance themselves + // on changes. There are implied line breaks _between_ the children of + // a node (but not before the first or after the last child). + class TextNode extends Text { + constructor(children, length) { + super(); + this.children = children; + this.length = length; + this.lines = 0; + for (let child of children) + this.lines += child.lines; + } + lineInner(target, isLine, line, offset) { + for (let i = 0;; i++) { + let child = this.children[i], end = offset + child.length, endLine = line + child.lines - 1; + if ((isLine ? endLine : end) >= target) + return child.lineInner(target, isLine, line, offset); + offset = end + 1; + line = endLine + 1; + } + } + decompose(from, to, target, open) { + for (let i = 0, pos = 0; pos <= to && i < this.children.length; i++) { + let child = this.children[i], end = pos + child.length; + if (from <= end && to >= pos) { + let childOpen = open & ((pos <= from ? 1 /* From */ : 0) | (end >= to ? 2 /* To */ : 0)); + if (pos >= from && end <= to && !childOpen) + target.push(child); + else + child.decompose(from - pos, to - pos, target, childOpen); + } + pos = end + 1; + } + } + replace(from, to, text) { + if (text.lines < this.lines) + for (let i = 0, pos = 0; i < this.children.length; i++) { + let child = this.children[i], end = pos + child.length; + // Fast path: if the change only affects one child and the + // child's size remains in the acceptable range, only update + // that child + if (from >= pos && to <= end) { + let updated = child.replace(from - pos, to - pos, text); + let totalLines = this.lines - child.lines + updated.lines; + if (updated.lines < (totalLines >> (5 /* BranchShift */ - 1)) && + updated.lines > (totalLines >> (5 /* BranchShift */ + 1))) { + let copy = this.children.slice(); + copy[i] = updated; + return new TextNode(copy, this.length - (to - from) + text.length); + } + return super.replace(pos, end, updated); + } + pos = end + 1; + } + return super.replace(from, to, text); + } + sliceString(from, to = this.length, lineSep = "\n") { + let result = ""; + for (let i = 0, pos = 0; i < this.children.length && pos <= to; i++) { + let child = this.children[i], end = pos + child.length; + if (pos > from && i) + result += lineSep; + if (from < end && to > pos) + result += child.sliceString(from - pos, to - pos, lineSep); + pos = end + 1; + } + return result; + } + flatten(target) { + for (let child of this.children) + child.flatten(target); + } + scanIdentical(other, dir) { + if (!(other instanceof TextNode)) + return 0; + let length = 0; + let [iA, iB, eA, eB] = dir > 0 ? [0, 0, this.children.length, other.children.length] + : [this.children.length - 1, other.children.length - 1, -1, -1]; + for (;; iA += dir, iB += dir) { + if (iA == eA || iB == eB) + return length; + let chA = this.children[iA], chB = other.children[iB]; + if (chA != chB) + return length + chA.scanIdentical(chB, dir); + length += chA.length + 1; + } + } + static from(children, length = children.reduce((l, ch) => l + ch.length + 1, -1)) { + let lines = 0; + for (let ch of children) + lines += ch.lines; + if (lines < 32 /* Branch */) { + let flat = []; + for (let ch of children) + ch.flatten(flat); + return new TextLeaf(flat, length); + } + let chunk = Math.max(32 /* Branch */, lines >> 5 /* BranchShift */), maxChunk = chunk << 1, minChunk = chunk >> 1; + let chunked = [], currentLines = 0, currentLen = -1, currentChunk = []; + function add(child) { + let last; + if (child.lines > maxChunk && child instanceof TextNode) { + for (let node of child.children) + add(node); + } + else if (child.lines > minChunk && (currentLines > minChunk || !currentLines)) { + flush(); + chunked.push(child); + } + else if (child instanceof TextLeaf && currentLines && + (last = currentChunk[currentChunk.length - 1]) instanceof TextLeaf && + child.lines + last.lines <= 32 /* Branch */) { + currentLines += child.lines; + currentLen += child.length + 1; + currentChunk[currentChunk.length - 1] = new TextLeaf(last.text.concat(child.text), last.length + 1 + child.length); + } + else { + if (currentLines + child.lines > chunk) + flush(); + currentLines += child.lines; + currentLen += child.length + 1; + currentChunk.push(child); + } + } + function flush() { + if (currentLines == 0) + return; + chunked.push(currentChunk.length == 1 ? currentChunk[0] : TextNode.from(currentChunk, currentLen)); + currentLen = -1; + currentLines = currentChunk.length = 0; + } + for (let child of children) + add(child); + flush(); + return chunked.length == 1 ? chunked[0] : new TextNode(chunked, length); + } + } + Text.empty = /*@__PURE__*/new TextLeaf([""], 0); + function textLength(text) { + let length = -1; + for (let line of text) + length += line.length + 1; + return length; + } + function appendText(text, target, from = 0, to = 1e9) { + for (let pos = 0, i = 0, first = true; i < text.length && pos <= to; i++) { + let line = text[i], end = pos + line.length; + if (end >= from) { + if (end > to) + line = line.slice(0, to - pos); + if (pos < from) + line = line.slice(from - pos); + if (first) { + target[target.length - 1] += line; + first = false; + } + else + target.push(line); + } + pos = end + 1; + } + return target; + } + function sliceText(text, from, to) { + return appendText(text, [""], from, to); + } + class RawTextCursor { + constructor(text, dir = 1) { + this.dir = dir; + this.done = false; + this.lineBreak = false; + this.value = ""; + this.nodes = [text]; + this.offsets = [dir > 0 ? 1 : (text instanceof TextLeaf ? text.text.length : text.children.length) << 1]; + } + nextInner(skip, dir) { + this.done = this.lineBreak = false; + for (;;) { + let last = this.nodes.length - 1; + let top = this.nodes[last], offsetValue = this.offsets[last], offset = offsetValue >> 1; + let size = top instanceof TextLeaf ? top.text.length : top.children.length; + if (offset == (dir > 0 ? size : 0)) { + if (last == 0) { + this.done = true; + this.value = ""; + return this; + } + if (dir > 0) + this.offsets[last - 1]++; + this.nodes.pop(); + this.offsets.pop(); + } + else if ((offsetValue & 1) == (dir > 0 ? 0 : 1)) { + this.offsets[last] += dir; + if (skip == 0) { + this.lineBreak = true; + this.value = "\n"; + return this; + } + skip--; + } + else if (top instanceof TextLeaf) { + // Move to the next string + let next = top.text[offset + (dir < 0 ? -1 : 0)]; + this.offsets[last] += dir; + if (next.length > Math.max(0, skip)) { + this.value = skip == 0 ? next : dir > 0 ? next.slice(skip) : next.slice(0, next.length - skip); + return this; + } + skip -= next.length; + } + else { + let next = top.children[offset + (dir < 0 ? -1 : 0)]; + if (skip > next.length) { + skip -= next.length; + this.offsets[last] += dir; + } + else { + if (dir < 0) + this.offsets[last]--; + this.nodes.push(next); + this.offsets.push(dir > 0 ? 1 : (next instanceof TextLeaf ? next.text.length : next.children.length) << 1); + } + } + } + } + next(skip = 0) { + if (skip < 0) { + this.nextInner(-skip, (-this.dir)); + skip = this.value.length; + } + return this.nextInner(skip, this.dir); + } + } + class PartialTextCursor { + constructor(text, start, end) { + this.value = ""; + this.done = false; + this.cursor = new RawTextCursor(text, start > end ? -1 : 1); + this.pos = start > end ? text.length : 0; + this.from = Math.min(start, end); + this.to = Math.max(start, end); + } + nextInner(skip, dir) { + if (dir < 0 ? this.pos <= this.from : this.pos >= this.to) { + this.value = ""; + this.done = true; + return this; + } + skip += Math.max(0, dir < 0 ? this.pos - this.to : this.from - this.pos); + let limit = dir < 0 ? this.pos - this.from : this.to - this.pos; + if (skip > limit) + skip = limit; + limit -= skip; + let { value } = this.cursor.next(skip); + this.pos += (value.length + skip) * dir; + this.value = value.length <= limit ? value : dir < 0 ? value.slice(value.length - limit) : value.slice(0, limit); + this.done = !this.value; + return this; + } + next(skip = 0) { + if (skip < 0) + skip = Math.max(skip, this.from - this.pos); + else if (skip > 0) + skip = Math.min(skip, this.to - this.pos); + return this.nextInner(skip, this.cursor.dir); + } + get lineBreak() { return this.cursor.lineBreak && this.value != ""; } + } + class LineCursor { + constructor(inner) { + this.inner = inner; + this.afterBreak = true; + this.value = ""; + this.done = false; + } + next(skip = 0) { + let { done, lineBreak, value } = this.inner.next(skip); + if (done) { + this.done = true; + this.value = ""; + } + else if (lineBreak) { + if (this.afterBreak) { + this.value = ""; + } + else { + this.afterBreak = true; + this.next(); + } + } + else { + this.value = value; + this.afterBreak = false; + } + return this; + } + get lineBreak() { return false; } + } + if (typeof Symbol != "undefined") { + Text.prototype[Symbol.iterator] = function () { return this.iter(); }; + RawTextCursor.prototype[Symbol.iterator] = PartialTextCursor.prototype[Symbol.iterator] = + LineCursor.prototype[Symbol.iterator] = function () { return this; }; + } + /** + This type describes a line in the document. It is created + on-demand when lines are [queried](https://codemirror.net/6/docs/ref/#state.Text.lineAt). + */ + class Line { + /** + @internal + */ + constructor( + /** + The position of the start of the line. + */ + from, + /** + The position at the end of the line (_before_ the line break, + or at the end of document for the last line). + */ + to, + /** + This line's line number (1-based). + */ + number, + /** + The line's content. + */ + text) { + this.from = from; + this.to = to; + this.number = number; + this.text = text; + } + /** + The length of the line (not including any line break after it). + */ + get length() { return this.to - this.from; } + } + + // Compressed representation of the Grapheme_Cluster_Break=Extend + // information from + // http://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakProperty.txt. + // Each pair of elements represents a range, as an offet from the + // previous range and a length. Numbers are in base-36, with the empty + // string being a shorthand for 1. + let extend = /*@__PURE__*/"lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(s => s ? parseInt(s, 36) : 1); + // Convert offsets into absolute values + for (let i = 1; i < extend.length; i++) + extend[i] += extend[i - 1]; + function isExtendingChar(code) { + for (let i = 1; i < extend.length; i += 2) + if (extend[i] > code) + return extend[i - 1] <= code; + return false; + } + function isRegionalIndicator(code) { + return code >= 0x1F1E6 && code <= 0x1F1FF; + } + const ZWJ = 0x200d; + /** + Returns a next grapheme cluster break _after_ (not equal to) + `pos`, if `forward` is true, or before otherwise. Returns `pos` + itself if no further cluster break is available in the string. + Moves across surrogate pairs, extending characters (when + `includeExtending` is true), characters joined with zero-width + joiners, and flag emoji. + */ + function findClusterBreak(str, pos, forward = true, includeExtending = true) { + return (forward ? nextClusterBreak : prevClusterBreak)(str, pos, includeExtending); + } + function nextClusterBreak(str, pos, includeExtending) { + if (pos == str.length) + return pos; + // If pos is in the middle of a surrogate pair, move to its start + if (pos && surrogateLow(str.charCodeAt(pos)) && surrogateHigh(str.charCodeAt(pos - 1))) + pos--; + let prev = codePointAt(str, pos); + pos += codePointSize(prev); + while (pos < str.length) { + let next = codePointAt(str, pos); + if (prev == ZWJ || next == ZWJ || includeExtending && isExtendingChar(next)) { + pos += codePointSize(next); + prev = next; + } + else if (isRegionalIndicator(next)) { + let countBefore = 0, i = pos - 2; + while (i >= 0 && isRegionalIndicator(codePointAt(str, i))) { + countBefore++; + i -= 2; + } + if (countBefore % 2 == 0) + break; + else + pos += 2; + } + else { + break; + } + } + return pos; + } + function prevClusterBreak(str, pos, includeExtending) { + while (pos > 0) { + let found = nextClusterBreak(str, pos - 2, includeExtending); + if (found < pos) + return found; + pos--; + } + return 0; + } + function surrogateLow(ch) { return ch >= 0xDC00 && ch < 0xE000; } + function surrogateHigh(ch) { return ch >= 0xD800 && ch < 0xDC00; } + /** + Find the code point at the given position in a string (like the + [`codePointAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) + string method). + */ + function codePointAt(str, pos) { + let code0 = str.charCodeAt(pos); + if (!surrogateHigh(code0) || pos + 1 == str.length) + return code0; + let code1 = str.charCodeAt(pos + 1); + if (!surrogateLow(code1)) + return code0; + return ((code0 - 0xd800) << 10) + (code1 - 0xdc00) + 0x10000; + } + /** + Given a Unicode codepoint, return the JavaScript string that + respresents it (like + [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint)). + */ + function fromCodePoint(code) { + if (code <= 0xffff) + return String.fromCharCode(code); + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xd800, (code & 1023) + 0xdc00); + } + /** + The amount of positions a character takes up a JavaScript string. + */ + function codePointSize(code) { return code < 0x10000 ? 1 : 2; } + + const DefaultSplit = /\r\n?|\n/; + /** + Distinguishes different ways in which positions can be mapped. + */ + var MapMode = /*@__PURE__*/(function (MapMode) { + /** + Map a position to a valid new position, even when its context + was deleted. + */ + MapMode[MapMode["Simple"] = 0] = "Simple"; + /** + Return null if deletion happens across the position. + */ + MapMode[MapMode["TrackDel"] = 1] = "TrackDel"; + /** + Return null if the character _before_ the position is deleted. + */ + MapMode[MapMode["TrackBefore"] = 2] = "TrackBefore"; + /** + Return null if the character _after_ the position is deleted. + */ + MapMode[MapMode["TrackAfter"] = 3] = "TrackAfter"; + return MapMode})(MapMode || (MapMode = {})); + /** + A change description is a variant of [change set](https://codemirror.net/6/docs/ref/#state.ChangeSet) + that doesn't store the inserted text. As such, it can't be + applied, but is cheaper to store and manipulate. + */ + class ChangeDesc { + // Sections are encoded as pairs of integers. The first is the + // length in the current document, and the second is -1 for + // unaffected sections, and the length of the replacement content + // otherwise. So an insertion would be (0, n>0), a deletion (n>0, + // 0), and a replacement two positive numbers. + /** + @internal + */ + constructor( + /** + @internal + */ + sections) { + this.sections = sections; + } + /** + The length of the document before the change. + */ + get length() { + let result = 0; + for (let i = 0; i < this.sections.length; i += 2) + result += this.sections[i]; + return result; + } + /** + The length of the document after the change. + */ + get newLength() { + let result = 0; + for (let i = 0; i < this.sections.length; i += 2) { + let ins = this.sections[i + 1]; + result += ins < 0 ? this.sections[i] : ins; + } + return result; + } + /** + False when there are actual changes in this set. + */ + get empty() { return this.sections.length == 0 || this.sections.length == 2 && this.sections[1] < 0; } + /** + Iterate over the unchanged parts left by these changes. `posA` + provides the position of the range in the old document, `posB` + the new position in the changed document. + */ + iterGaps(f) { + for (let i = 0, posA = 0, posB = 0; i < this.sections.length;) { + let len = this.sections[i++], ins = this.sections[i++]; + if (ins < 0) { + f(posA, posB, len); + posB += len; + } + else { + posB += ins; + } + posA += len; + } + } + /** + Iterate over the ranges changed by these changes. (See + [`ChangeSet.iterChanges`](https://codemirror.net/6/docs/ref/#state.ChangeSet.iterChanges) for a + variant that also provides you with the inserted text.) + `fromA`/`toA` provides the extent of the change in the starting + document, `fromB`/`toB` the extent of the replacement in the + changed document. + + When `individual` is true, adjacent changes (which are kept + separate for [position mapping](https://codemirror.net/6/docs/ref/#state.ChangeDesc.mapPos)) are + reported separately. + */ + iterChangedRanges(f, individual = false) { + iterChanges(this, f, individual); + } + /** + Get a description of the inverted form of these changes. + */ + get invertedDesc() { + let sections = []; + for (let i = 0; i < this.sections.length;) { + let len = this.sections[i++], ins = this.sections[i++]; + if (ins < 0) + sections.push(len, ins); + else + sections.push(ins, len); + } + return new ChangeDesc(sections); + } + /** + Compute the combined effect of applying another set of changes + after this one. The length of the document after this set should + match the length before `other`. + */ + composeDesc(other) { return this.empty ? other : other.empty ? this : composeSets(this, other); } + /** + Map this description, which should start with the same document + as `other`, over another set of changes, so that it can be + applied after it. When `before` is true, map as if the changes + in `other` happened before the ones in `this`. + */ + mapDesc(other, before = false) { return other.empty ? this : mapSet(this, other, before); } + mapPos(pos, assoc = -1, mode = MapMode.Simple) { + let posA = 0, posB = 0; + for (let i = 0; i < this.sections.length;) { + let len = this.sections[i++], ins = this.sections[i++], endA = posA + len; + if (ins < 0) { + if (endA > pos) + return posB + (pos - posA); + posB += len; + } + else { + if (mode != MapMode.Simple && endA >= pos && + (mode == MapMode.TrackDel && posA < pos && endA > pos || + mode == MapMode.TrackBefore && posA < pos || + mode == MapMode.TrackAfter && endA > pos)) + return null; + if (endA > pos || endA == pos && assoc < 0 && !len) + return pos == posA || assoc < 0 ? posB : posB + ins; + posB += ins; + } + posA = endA; + } + if (pos > posA) + throw new RangeError(`Position ${pos} is out of range for changeset of length ${posA}`); + return posB; + } + /** + Check whether these changes touch a given range. When one of the + changes entirely covers the range, the string `"cover"` is + returned. + */ + touchesRange(from, to = from) { + for (let i = 0, pos = 0; i < this.sections.length && pos <= to;) { + let len = this.sections[i++], ins = this.sections[i++], end = pos + len; + if (ins >= 0 && pos <= to && end >= from) + return pos < from && end > to ? "cover" : true; + pos = end; + } + return false; + } + /** + @internal + */ + toString() { + let result = ""; + for (let i = 0; i < this.sections.length;) { + let len = this.sections[i++], ins = this.sections[i++]; + result += (result ? " " : "") + len + (ins >= 0 ? ":" + ins : ""); + } + return result; + } + /** + Serialize this change desc to a JSON-representable value. + */ + toJSON() { return this.sections; } + /** + Create a change desc from its JSON representation (as produced + by [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeDesc.toJSON). + */ + static fromJSON(json) { + if (!Array.isArray(json) || json.length % 2 || json.some(a => typeof a != "number")) + throw new RangeError("Invalid JSON representation of ChangeDesc"); + return new ChangeDesc(json); + } + /** + @internal + */ + static create(sections) { return new ChangeDesc(sections); } + } + /** + A change set represents a group of modifications to a document. It + stores the document length, and can only be applied to documents + with exactly that length. + */ + class ChangeSet extends ChangeDesc { + constructor(sections, + /** + @internal + */ + inserted) { + super(sections); + this.inserted = inserted; + } + /** + Apply the changes to a document, returning the modified + document. + */ + apply(doc) { + if (this.length != doc.length) + throw new RangeError("Applying change set to a document with the wrong length"); + iterChanges(this, (fromA, toA, fromB, _toB, text) => doc = doc.replace(fromB, fromB + (toA - fromA), text), false); + return doc; + } + mapDesc(other, before = false) { return mapSet(this, other, before, true); } + /** + Given the document as it existed _before_ the changes, return a + change set that represents the inverse of this set, which could + be used to go from the document created by the changes back to + the document as it existed before the changes. + */ + invert(doc) { + let sections = this.sections.slice(), inserted = []; + for (let i = 0, pos = 0; i < sections.length; i += 2) { + let len = sections[i], ins = sections[i + 1]; + if (ins >= 0) { + sections[i] = ins; + sections[i + 1] = len; + let index = i >> 1; + while (inserted.length < index) + inserted.push(Text.empty); + inserted.push(len ? doc.slice(pos, pos + len) : Text.empty); + } + pos += len; + } + return new ChangeSet(sections, inserted); + } + /** + Combine two subsequent change sets into a single set. `other` + must start in the document produced by `this`. If `this` goes + `docA` → `docB` and `other` represents `docB` → `docC`, the + returned value will represent the change `docA` → `docC`. + */ + compose(other) { return this.empty ? other : other.empty ? this : composeSets(this, other, true); } + /** + Given another change set starting in the same document, maps this + change set over the other, producing a new change set that can be + applied to the document produced by applying `other`. When + `before` is `true`, order changes as if `this` comes before + `other`, otherwise (the default) treat `other` as coming first. + + Given two changes `A` and `B`, `A.compose(B.map(A))` and + `B.compose(A.map(B, true))` will produce the same document. This + provides a basic form of [operational + transformation](https://en.wikipedia.org/wiki/Operational_transformation), + and can be used for collaborative editing. + */ + map(other, before = false) { return other.empty ? this : mapSet(this, other, before, true); } + /** + Iterate over the changed ranges in the document, calling `f` for + each, with the range in the original document (`fromA`-`toA`) + and the range that replaces it in the new document + (`fromB`-`toB`). + + When `individual` is true, adjacent changes are reported + separately. + */ + iterChanges(f, individual = false) { + iterChanges(this, f, individual); + } + /** + Get a [change description](https://codemirror.net/6/docs/ref/#state.ChangeDesc) for this change + set. + */ + get desc() { return ChangeDesc.create(this.sections); } + /** + @internal + */ + filter(ranges) { + let resultSections = [], resultInserted = [], filteredSections = []; + let iter = new SectionIter(this); + done: for (let i = 0, pos = 0;;) { + let next = i == ranges.length ? 1e9 : ranges[i++]; + while (pos < next || pos == next && iter.len == 0) { + if (iter.done) + break done; + let len = Math.min(iter.len, next - pos); + addSection(filteredSections, len, -1); + let ins = iter.ins == -1 ? -1 : iter.off == 0 ? iter.ins : 0; + addSection(resultSections, len, ins); + if (ins > 0) + addInsert(resultInserted, resultSections, iter.text); + iter.forward(len); + pos += len; + } + let end = ranges[i++]; + while (pos < end) { + if (iter.done) + break done; + let len = Math.min(iter.len, end - pos); + addSection(resultSections, len, -1); + addSection(filteredSections, len, iter.ins == -1 ? -1 : iter.off == 0 ? iter.ins : 0); + iter.forward(len); + pos += len; + } + } + return { changes: new ChangeSet(resultSections, resultInserted), + filtered: ChangeDesc.create(filteredSections) }; + } + /** + Serialize this change set to a JSON-representable value. + */ + toJSON() { + let parts = []; + for (let i = 0; i < this.sections.length; i += 2) { + let len = this.sections[i], ins = this.sections[i + 1]; + if (ins < 0) + parts.push(len); + else if (ins == 0) + parts.push([len]); + else + parts.push([len].concat(this.inserted[i >> 1].toJSON())); + } + return parts; + } + /** + Create a change set for the given changes, for a document of the + given length, using `lineSep` as line separator. + */ + static of(changes, length, lineSep) { + let sections = [], inserted = [], pos = 0; + let total = null; + function flush(force = false) { + if (!force && !sections.length) + return; + if (pos < length) + addSection(sections, length - pos, -1); + let set = new ChangeSet(sections, inserted); + total = total ? total.compose(set.map(total)) : set; + sections = []; + inserted = []; + pos = 0; + } + function process(spec) { + if (Array.isArray(spec)) { + for (let sub of spec) + process(sub); + } + else if (spec instanceof ChangeSet) { + if (spec.length != length) + throw new RangeError(`Mismatched change set length (got ${spec.length}, expected ${length})`); + flush(); + total = total ? total.compose(spec.map(total)) : spec; + } + else { + let { from, to = from, insert } = spec; + if (from > to || from < 0 || to > length) + throw new RangeError(`Invalid change range ${from} to ${to} (in doc of length ${length})`); + let insText = !insert ? Text.empty : typeof insert == "string" ? Text.of(insert.split(lineSep || DefaultSplit)) : insert; + let insLen = insText.length; + if (from == to && insLen == 0) + return; + if (from < pos) + flush(); + if (from > pos) + addSection(sections, from - pos, -1); + addSection(sections, to - from, insLen); + addInsert(inserted, sections, insText); + pos = to; + } + } + process(changes); + flush(!total); + return total; + } + /** + Create an empty changeset of the given length. + */ + static empty(length) { + return new ChangeSet(length ? [length, -1] : [], []); + } + /** + Create a changeset from its JSON representation (as produced by + [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeSet.toJSON). + */ + static fromJSON(json) { + if (!Array.isArray(json)) + throw new RangeError("Invalid JSON representation of ChangeSet"); + let sections = [], inserted = []; + for (let i = 0; i < json.length; i++) { + let part = json[i]; + if (typeof part == "number") { + sections.push(part, -1); + } + else if (!Array.isArray(part) || typeof part[0] != "number" || part.some((e, i) => i && typeof e != "string")) { + throw new RangeError("Invalid JSON representation of ChangeSet"); + } + else if (part.length == 1) { + sections.push(part[0], 0); + } + else { + while (inserted.length < i) + inserted.push(Text.empty); + inserted[i] = Text.of(part.slice(1)); + sections.push(part[0], inserted[i].length); + } + } + return new ChangeSet(sections, inserted); + } + /** + @internal + */ + static createSet(sections, inserted) { + return new ChangeSet(sections, inserted); + } + } + function addSection(sections, len, ins, forceJoin = false) { + if (len == 0 && ins <= 0) + return; + let last = sections.length - 2; + if (last >= 0 && ins <= 0 && ins == sections[last + 1]) + sections[last] += len; + else if (len == 0 && sections[last] == 0) + sections[last + 1] += ins; + else if (forceJoin) { + sections[last] += len; + sections[last + 1] += ins; + } + else + sections.push(len, ins); + } + function addInsert(values, sections, value) { + if (value.length == 0) + return; + let index = (sections.length - 2) >> 1; + if (index < values.length) { + values[values.length - 1] = values[values.length - 1].append(value); + } + else { + while (values.length < index) + values.push(Text.empty); + values.push(value); + } + } + function iterChanges(desc, f, individual) { + let inserted = desc.inserted; + for (let posA = 0, posB = 0, i = 0; i < desc.sections.length;) { + let len = desc.sections[i++], ins = desc.sections[i++]; + if (ins < 0) { + posA += len; + posB += len; + } + else { + let endA = posA, endB = posB, text = Text.empty; + for (;;) { + endA += len; + endB += ins; + if (ins && inserted) + text = text.append(inserted[(i - 2) >> 1]); + if (individual || i == desc.sections.length || desc.sections[i + 1] < 0) + break; + len = desc.sections[i++]; + ins = desc.sections[i++]; + } + f(posA, endA, posB, endB, text); + posA = endA; + posB = endB; + } + } + } + function mapSet(setA, setB, before, mkSet = false) { + let sections = [], insert = mkSet ? [] : null; + let a = new SectionIter(setA), b = new SectionIter(setB); + for (let posA = 0, posB = 0;;) { + if (a.ins == -1) { + posA += a.len; + a.next(); + } + else if (b.ins == -1 && posB < posA) { + let skip = Math.min(b.len, posA - posB); + b.forward(skip); + addSection(sections, skip, -1); + posB += skip; + } + else if (b.ins >= 0 && (a.done || posB < posA || posB == posA && (b.len < a.len || b.len == a.len && !before))) { + addSection(sections, b.ins, -1); + while (posA > posB && !a.done && posA + a.len < posB + b.len) { + posA += a.len; + a.next(); + } + posB += b.len; + b.next(); + } + else if (a.ins >= 0) { + let len = 0, end = posA + a.len; + for (;;) { + if (b.ins >= 0 && posB > posA && posB + b.len < end) { + len += b.ins; + posB += b.len; + b.next(); + } + else if (b.ins == -1 && posB < end) { + let skip = Math.min(b.len, end - posB); + len += skip; + b.forward(skip); + posB += skip; + } + else { + break; + } + } + addSection(sections, len, a.ins); + if (insert) + addInsert(insert, sections, a.text); + posA = end; + a.next(); + } + else if (a.done && b.done) { + return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections); + } + else { + throw new Error("Mismatched change set lengths"); + } + } + } + function composeSets(setA, setB, mkSet = false) { + let sections = []; + let insert = mkSet ? [] : null; + let a = new SectionIter(setA), b = new SectionIter(setB); + for (let open = false;;) { + if (a.done && b.done) { + return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections); + } + else if (a.ins == 0) { // Deletion in A + addSection(sections, a.len, 0, open); + a.next(); + } + else if (b.len == 0 && !b.done) { // Insertion in B + addSection(sections, 0, b.ins, open); + if (insert) + addInsert(insert, sections, b.text); + b.next(); + } + else if (a.done || b.done) { + throw new Error("Mismatched change set lengths"); + } + else { + let len = Math.min(a.len2, b.len), sectionLen = sections.length; + if (a.ins == -1) { + let insB = b.ins == -1 ? -1 : b.off ? 0 : b.ins; + addSection(sections, len, insB, open); + if (insert && insB) + addInsert(insert, sections, b.text); + } + else if (b.ins == -1) { + addSection(sections, a.off ? 0 : a.len, len, open); + if (insert) + addInsert(insert, sections, a.textBit(len)); + } + else { + addSection(sections, a.off ? 0 : a.len, b.off ? 0 : b.ins, open); + if (insert && !b.off) + addInsert(insert, sections, b.text); + } + open = (a.ins > len || b.ins >= 0 && b.len > len) && (open || sections.length > sectionLen); + a.forward2(len); + b.forward(len); + } + } + } + class SectionIter { + constructor(set) { + this.set = set; + this.i = 0; + this.next(); + } + next() { + let { sections } = this.set; + if (this.i < sections.length) { + this.len = sections[this.i++]; + this.ins = sections[this.i++]; + } + else { + this.len = 0; + this.ins = -2; + } + this.off = 0; + } + get done() { return this.ins == -2; } + get len2() { return this.ins < 0 ? this.len : this.ins; } + get text() { + let { inserted } = this.set, index = (this.i - 2) >> 1; + return index >= inserted.length ? Text.empty : inserted[index]; + } + textBit(len) { + let { inserted } = this.set, index = (this.i - 2) >> 1; + return index >= inserted.length && !len ? Text.empty + : inserted[index].slice(this.off, len == null ? undefined : this.off + len); + } + forward(len) { + if (len == this.len) + this.next(); + else { + this.len -= len; + this.off += len; + } + } + forward2(len) { + if (this.ins == -1) + this.forward(len); + else if (len == this.ins) + this.next(); + else { + this.ins -= len; + this.off += len; + } + } + } + + /** + A single selection range. When + [`allowMultipleSelections`](https://codemirror.net/6/docs/ref/#state.EditorState^allowMultipleSelections) + is enabled, a [selection](https://codemirror.net/6/docs/ref/#state.EditorSelection) may hold + multiple ranges. By default, selections hold exactly one range. + */ + class SelectionRange { + constructor( + /** + The lower boundary of the range. + */ + from, + /** + The upper boundary of the range. + */ + to, flags) { + this.from = from; + this.to = to; + this.flags = flags; + } + /** + The anchor of the range—the side that doesn't move when you + extend it. + */ + get anchor() { return this.flags & 16 /* Inverted */ ? this.to : this.from; } + /** + The head of the range, which is moved when the range is + [extended](https://codemirror.net/6/docs/ref/#state.SelectionRange.extend). + */ + get head() { return this.flags & 16 /* Inverted */ ? this.from : this.to; } + /** + True when `anchor` and `head` are at the same position. + */ + get empty() { return this.from == this.to; } + /** + If this is a cursor that is explicitly associated with the + character on one of its sides, this returns the side. -1 means + the character before its position, 1 the character after, and 0 + means no association. + */ + get assoc() { return this.flags & 4 /* AssocBefore */ ? -1 : this.flags & 8 /* AssocAfter */ ? 1 : 0; } + /** + The bidirectional text level associated with this cursor, if + any. + */ + get bidiLevel() { + let level = this.flags & 3 /* BidiLevelMask */; + return level == 3 ? null : level; + } + /** + The goal column (stored vertical offset) associated with a + cursor. This is used to preserve the vertical position when + [moving](https://codemirror.net/6/docs/ref/#view.EditorView.moveVertically) across + lines of different length. + */ + get goalColumn() { + let value = this.flags >> 5 /* GoalColumnOffset */; + return value == 33554431 /* NoGoalColumn */ ? undefined : value; + } + /** + Map this range through a change, producing a valid range in the + updated document. + */ + map(change, assoc = -1) { + let from, to; + if (this.empty) { + from = to = change.mapPos(this.from, assoc); + } + else { + from = change.mapPos(this.from, 1); + to = change.mapPos(this.to, -1); + } + return from == this.from && to == this.to ? this : new SelectionRange(from, to, this.flags); + } + /** + Extend this range to cover at least `from` to `to`. + */ + extend(from, to = from) { + if (from <= this.anchor && to >= this.anchor) + return EditorSelection.range(from, to); + let head = Math.abs(from - this.anchor) > Math.abs(to - this.anchor) ? from : to; + return EditorSelection.range(this.anchor, head); + } + /** + Compare this range to another range. + */ + eq(other) { + return this.anchor == other.anchor && this.head == other.head; + } + /** + Return a JSON-serializable object representing the range. + */ + toJSON() { return { anchor: this.anchor, head: this.head }; } + /** + Convert a JSON representation of a range to a `SelectionRange` + instance. + */ + static fromJSON(json) { + if (!json || typeof json.anchor != "number" || typeof json.head != "number") + throw new RangeError("Invalid JSON representation for SelectionRange"); + return EditorSelection.range(json.anchor, json.head); + } + /** + @internal + */ + static create(from, to, flags) { + return new SelectionRange(from, to, flags); + } + } + /** + An editor selection holds one or more selection ranges. + */ + class EditorSelection { + constructor( + /** + The ranges in the selection, sorted by position. Ranges cannot + overlap (but they may touch, if they aren't empty). + */ + ranges, + /** + The index of the _main_ range in the selection (which is + usually the range that was added last). + */ + mainIndex) { + this.ranges = ranges; + this.mainIndex = mainIndex; + } + /** + Map a selection through a change. Used to adjust the selection + position for changes. + */ + map(change, assoc = -1) { + if (change.empty) + return this; + return EditorSelection.create(this.ranges.map(r => r.map(change, assoc)), this.mainIndex); + } + /** + Compare this selection to another selection. + */ + eq(other) { + if (this.ranges.length != other.ranges.length || + this.mainIndex != other.mainIndex) + return false; + for (let i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].eq(other.ranges[i])) + return false; + return true; + } + /** + Get the primary selection range. Usually, you should make sure + your code applies to _all_ ranges, by using methods like + [`changeByRange`](https://codemirror.net/6/docs/ref/#state.EditorState.changeByRange). + */ + get main() { return this.ranges[this.mainIndex]; } + /** + Make sure the selection only has one range. Returns a selection + holding only the main range from this selection. + */ + asSingle() { + return this.ranges.length == 1 ? this : new EditorSelection([this.main], 0); + } + /** + Extend this selection with an extra range. + */ + addRange(range, main = true) { + return EditorSelection.create([range].concat(this.ranges), main ? 0 : this.mainIndex + 1); + } + /** + Replace a given range with another range, and then normalize the + selection to merge and sort ranges if necessary. + */ + replaceRange(range, which = this.mainIndex) { + let ranges = this.ranges.slice(); + ranges[which] = range; + return EditorSelection.create(ranges, this.mainIndex); + } + /** + Convert this selection to an object that can be serialized to + JSON. + */ + toJSON() { + return { ranges: this.ranges.map(r => r.toJSON()), main: this.mainIndex }; + } + /** + Create a selection from a JSON representation. + */ + static fromJSON(json) { + if (!json || !Array.isArray(json.ranges) || typeof json.main != "number" || json.main >= json.ranges.length) + throw new RangeError("Invalid JSON representation for EditorSelection"); + return new EditorSelection(json.ranges.map((r) => SelectionRange.fromJSON(r)), json.main); + } + /** + Create a selection holding a single range. + */ + static single(anchor, head = anchor) { + return new EditorSelection([EditorSelection.range(anchor, head)], 0); + } + /** + Sort and merge the given set of ranges, creating a valid + selection. + */ + static create(ranges, mainIndex = 0) { + if (ranges.length == 0) + throw new RangeError("A selection needs at least one range"); + for (let pos = 0, i = 0; i < ranges.length; i++) { + let range = ranges[i]; + if (range.empty ? range.from <= pos : range.from < pos) + return EditorSelection.normalized(ranges.slice(), mainIndex); + pos = range.to; + } + return new EditorSelection(ranges, mainIndex); + } + /** + Create a cursor selection range at the given position. You can + safely ignore the optional arguments in most situations. + */ + static cursor(pos, assoc = 0, bidiLevel, goalColumn) { + return SelectionRange.create(pos, pos, (assoc == 0 ? 0 : assoc < 0 ? 4 /* AssocBefore */ : 8 /* AssocAfter */) | + (bidiLevel == null ? 3 : Math.min(2, bidiLevel)) | + ((goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* NoGoalColumn */) << 5 /* GoalColumnOffset */)); + } + /** + Create a selection range. + */ + static range(anchor, head, goalColumn) { + let goal = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* NoGoalColumn */) << 5 /* GoalColumnOffset */; + return head < anchor ? SelectionRange.create(head, anchor, 16 /* Inverted */ | goal | 8 /* AssocAfter */) + : SelectionRange.create(anchor, head, goal | (head > anchor ? 4 /* AssocBefore */ : 0)); + } + /** + @internal + */ + static normalized(ranges, mainIndex = 0) { + let main = ranges[mainIndex]; + ranges.sort((a, b) => a.from - b.from); + mainIndex = ranges.indexOf(main); + for (let i = 1; i < ranges.length; i++) { + let range = ranges[i], prev = ranges[i - 1]; + if (range.empty ? range.from <= prev.to : range.from < prev.to) { + let from = prev.from, to = Math.max(range.to, prev.to); + if (i <= mainIndex) + mainIndex--; + ranges.splice(--i, 2, range.anchor > range.head ? EditorSelection.range(to, from) : EditorSelection.range(from, to)); + } + } + return new EditorSelection(ranges, mainIndex); + } + } + function checkSelection(selection, docLength) { + for (let range of selection.ranges) + if (range.to > docLength) + throw new RangeError("Selection points outside of document"); + } + + let nextID = 0; + /** + A facet is a labeled value that is associated with an editor + state. It takes inputs from any number of extensions, and combines + those into a single output value. + + Examples of uses of facets are the [tab + size](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize), [editor + attributes](https://codemirror.net/6/docs/ref/#view.EditorView^editorAttributes), and [update + listeners](https://codemirror.net/6/docs/ref/#view.EditorView^updateListener). + */ + class Facet { + constructor( + /** + @internal + */ + combine, + /** + @internal + */ + compareInput, + /** + @internal + */ + compare, isStatic, + /** + @internal + */ + extensions) { + this.combine = combine; + this.compareInput = compareInput; + this.compare = compare; + this.isStatic = isStatic; + this.extensions = extensions; + /** + @internal + */ + this.id = nextID++; + this.default = combine([]); + } + /** + Define a new facet. + */ + static define(config = {}) { + return new Facet(config.combine || ((a) => a), config.compareInput || ((a, b) => a === b), config.compare || (!config.combine ? sameArray$1 : (a, b) => a === b), !!config.static, config.enables); + } + /** + Returns an extension that adds the given value to this facet. + */ + of(value) { + return new FacetProvider([], this, 0 /* Static */, value); + } + /** + Create an extension that computes a value for the facet from a + state. You must take care to declare the parts of the state that + this value depends on, since your function is only called again + for a new state when one of those parts changed. + + In cases where your value depends only on a single field, you'll + want to use the [`from`](https://codemirror.net/6/docs/ref/#state.Facet.from) method instead. + */ + compute(deps, get) { + if (this.isStatic) + throw new Error("Can't compute a static facet"); + return new FacetProvider(deps, this, 1 /* Single */, get); + } + /** + Create an extension that computes zero or more values for this + facet from a state. + */ + computeN(deps, get) { + if (this.isStatic) + throw new Error("Can't compute a static facet"); + return new FacetProvider(deps, this, 2 /* Multi */, get); + } + from(field, get) { + if (!get) + get = x => x; + return this.compute([field], state => get(state.field(field))); + } + } + function sameArray$1(a, b) { + return a == b || a.length == b.length && a.every((e, i) => e === b[i]); + } + class FacetProvider { + constructor(dependencies, facet, type, value) { + this.dependencies = dependencies; + this.facet = facet; + this.type = type; + this.value = value; + this.id = nextID++; + } + dynamicSlot(addresses) { + var _a; + let getter = this.value; + let compare = this.facet.compareInput; + let id = this.id, idx = addresses[id] >> 1, multi = this.type == 2 /* Multi */; + let depDoc = false, depSel = false, depAddrs = []; + for (let dep of this.dependencies) { + if (dep == "doc") + depDoc = true; + else if (dep == "selection") + depSel = true; + else if ((((_a = addresses[dep.id]) !== null && _a !== void 0 ? _a : 1) & 1) == 0) + depAddrs.push(addresses[dep.id]); + } + return { + create(state) { + state.values[idx] = getter(state); + return 1 /* Changed */; + }, + update(state, tr) { + if ((depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) || ensureAll(state, depAddrs)) { + let newVal = getter(state); + if (multi ? !compareArray(newVal, state.values[idx], compare) : !compare(newVal, state.values[idx])) { + state.values[idx] = newVal; + return 1 /* Changed */; + } + } + return 0; + }, + reconfigure: (state, oldState) => { + let newVal = getter(state); + let oldAddr = oldState.config.address[id]; + if (oldAddr != null) { + let oldVal = getAddr(oldState, oldAddr); + if (this.dependencies.every(dep => { + return dep instanceof Facet ? oldState.facet(dep) === state.facet(dep) : + dep instanceof StateField ? oldState.field(dep, false) == state.field(dep, false) : true; + }) || (multi ? compareArray(newVal, oldVal, compare) : compare(newVal, oldVal))) { + state.values[idx] = oldVal; + return 0; + } + } + state.values[idx] = newVal; + return 1 /* Changed */; + } + }; + } + } + function compareArray(a, b, compare) { + if (a.length != b.length) + return false; + for (let i = 0; i < a.length; i++) + if (!compare(a[i], b[i])) + return false; + return true; + } + function ensureAll(state, addrs) { + let changed = false; + for (let addr of addrs) + if (ensureAddr(state, addr) & 1 /* Changed */) + changed = true; + return changed; + } + function dynamicFacetSlot(addresses, facet, providers) { + let providerAddrs = providers.map(p => addresses[p.id]); + let providerTypes = providers.map(p => p.type); + let dynamic = providerAddrs.filter(p => !(p & 1)); + let idx = addresses[facet.id] >> 1; + function get(state) { + let values = []; + for (let i = 0; i < providerAddrs.length; i++) { + let value = getAddr(state, providerAddrs[i]); + if (providerTypes[i] == 2 /* Multi */) + for (let val of value) + values.push(val); + else + values.push(value); + } + return facet.combine(values); + } + return { + create(state) { + for (let addr of providerAddrs) + ensureAddr(state, addr); + state.values[idx] = get(state); + return 1 /* Changed */; + }, + update(state, tr) { + if (!ensureAll(state, dynamic)) + return 0; + let value = get(state); + if (facet.compare(value, state.values[idx])) + return 0; + state.values[idx] = value; + return 1 /* Changed */; + }, + reconfigure(state, oldState) { + let depChanged = ensureAll(state, providerAddrs); + let oldProviders = oldState.config.facets[facet.id], oldValue = oldState.facet(facet); + if (oldProviders && !depChanged && sameArray$1(providers, oldProviders)) { + state.values[idx] = oldValue; + return 0; + } + let value = get(state); + if (facet.compare(value, oldValue)) { + state.values[idx] = oldValue; + return 0; + } + state.values[idx] = value; + return 1 /* Changed */; + } + }; + } + const initField = /*@__PURE__*/Facet.define({ static: true }); + /** + Fields can store additional information in an editor state, and + keep it in sync with the rest of the state. + */ + class StateField { + constructor( + /** + @internal + */ + id, createF, updateF, compareF, + /** + @internal + */ + spec) { + this.id = id; + this.createF = createF; + this.updateF = updateF; + this.compareF = compareF; + this.spec = spec; + /** + @internal + */ + this.provides = undefined; + } + /** + Define a state field. + */ + static define(config) { + let field = new StateField(nextID++, config.create, config.update, config.compare || ((a, b) => a === b), config); + if (config.provide) + field.provides = config.provide(field); + return field; + } + create(state) { + let init = state.facet(initField).find(i => i.field == this); + return ((init === null || init === void 0 ? void 0 : init.create) || this.createF)(state); + } + /** + @internal + */ + slot(addresses) { + let idx = addresses[this.id] >> 1; + return { + create: (state) => { + state.values[idx] = this.create(state); + return 1 /* Changed */; + }, + update: (state, tr) => { + let oldVal = state.values[idx]; + let value = this.updateF(oldVal, tr); + if (this.compareF(oldVal, value)) + return 0; + state.values[idx] = value; + return 1 /* Changed */; + }, + reconfigure: (state, oldState) => { + if (oldState.config.address[this.id] != null) { + state.values[idx] = oldState.field(this); + return 0; + } + state.values[idx] = this.create(state); + return 1 /* Changed */; + } + }; + } + /** + Returns an extension that enables this field and overrides the + way it is initialized. Can be useful when you need to provide a + non-default starting value for the field. + */ + init(create) { + return [this, initField.of({ field: this, create })]; + } + /** + State field instances can be used as + [`Extension`](https://codemirror.net/6/docs/ref/#state.Extension) values to enable the field in a + given state. + */ + get extension() { return this; } + } + const Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 }; + function prec(value) { + return (ext) => new PrecExtension(ext, value); + } + /** + By default extensions are registered in the order they are found + in the flattened form of nested array that was provided. + Individual extension values can be assigned a precedence to + override this. Extensions that do not have a precedence set get + the precedence of the nearest parent with a precedence, or + [`default`](https://codemirror.net/6/docs/ref/#state.Prec.default) if there is no such parent. The + final ordering of extensions is determined by first sorting by + precedence and then by order within each precedence. + */ + const Prec = { + /** + The highest precedence level, for extensions that should end up + near the start of the precedence ordering. + */ + highest: /*@__PURE__*/prec(Prec_.highest), + /** + A higher-than-default precedence, for extensions that should + come before those with default precedence. + */ + high: /*@__PURE__*/prec(Prec_.high), + /** + The default precedence, which is also used for extensions + without an explicit precedence. + */ + default: /*@__PURE__*/prec(Prec_.default), + /** + A lower-than-default precedence. + */ + low: /*@__PURE__*/prec(Prec_.low), + /** + The lowest precedence level. Meant for things that should end up + near the end of the extension order. + */ + lowest: /*@__PURE__*/prec(Prec_.lowest) + }; + class PrecExtension { + constructor(inner, prec) { + this.inner = inner; + this.prec = prec; + } + } + /** + Extension compartments can be used to make a configuration + dynamic. By [wrapping](https://codemirror.net/6/docs/ref/#state.Compartment.of) part of your + configuration in a compartment, you can later + [replace](https://codemirror.net/6/docs/ref/#state.Compartment.reconfigure) that part through a + transaction. + */ + class Compartment { + /** + Create an instance of this compartment to add to your [state + configuration](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions). + */ + of(ext) { return new CompartmentInstance(this, ext); } + /** + Create an [effect](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) that + reconfigures this compartment. + */ + reconfigure(content) { + return Compartment.reconfigure.of({ compartment: this, extension: content }); + } + /** + Get the current content of the compartment in the state, or + `undefined` if it isn't present. + */ + get(state) { + return state.config.compartments.get(this); + } + } + class CompartmentInstance { + constructor(compartment, inner) { + this.compartment = compartment; + this.inner = inner; + } + } + class Configuration { + constructor(base, compartments, dynamicSlots, address, staticValues, facets) { + this.base = base; + this.compartments = compartments; + this.dynamicSlots = dynamicSlots; + this.address = address; + this.staticValues = staticValues; + this.facets = facets; + this.statusTemplate = []; + while (this.statusTemplate.length < dynamicSlots.length) + this.statusTemplate.push(0 /* Unresolved */); + } + staticFacet(facet) { + let addr = this.address[facet.id]; + return addr == null ? facet.default : this.staticValues[addr >> 1]; + } + static resolve(base, compartments, oldState) { + let fields = []; + let facets = Object.create(null); + let newCompartments = new Map(); + for (let ext of flatten(base, compartments, newCompartments)) { + if (ext instanceof StateField) + fields.push(ext); + else + (facets[ext.facet.id] || (facets[ext.facet.id] = [])).push(ext); + } + let address = Object.create(null); + let staticValues = []; + let dynamicSlots = []; + for (let field of fields) { + address[field.id] = dynamicSlots.length << 1; + dynamicSlots.push(a => field.slot(a)); + } + let oldFacets = oldState === null || oldState === void 0 ? void 0 : oldState.config.facets; + for (let id in facets) { + let providers = facets[id], facet = providers[0].facet; + let oldProviders = oldFacets && oldFacets[id] || []; + if (providers.every(p => p.type == 0 /* Static */)) { + address[facet.id] = (staticValues.length << 1) | 1; + if (sameArray$1(oldProviders, providers)) { + staticValues.push(oldState.facet(facet)); + } + else { + let value = facet.combine(providers.map(p => p.value)); + staticValues.push(oldState && facet.compare(value, oldState.facet(facet)) ? oldState.facet(facet) : value); + } + } + else { + for (let p of providers) { + if (p.type == 0 /* Static */) { + address[p.id] = (staticValues.length << 1) | 1; + staticValues.push(p.value); + } + else { + address[p.id] = dynamicSlots.length << 1; + dynamicSlots.push(a => p.dynamicSlot(a)); + } + } + address[facet.id] = dynamicSlots.length << 1; + dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers)); + } + } + let dynamic = dynamicSlots.map(f => f(address)); + return new Configuration(base, newCompartments, dynamic, address, staticValues, facets); + } + } + function flatten(extension, compartments, newCompartments) { + let result = [[], [], [], [], []]; + let seen = new Map(); + function inner(ext, prec) { + let known = seen.get(ext); + if (known != null) { + if (known <= prec) + return; + let found = result[known].indexOf(ext); + if (found > -1) + result[known].splice(found, 1); + if (ext instanceof CompartmentInstance) + newCompartments.delete(ext.compartment); + } + seen.set(ext, prec); + if (Array.isArray(ext)) { + for (let e of ext) + inner(e, prec); + } + else if (ext instanceof CompartmentInstance) { + if (newCompartments.has(ext.compartment)) + throw new RangeError(`Duplicate use of compartment in extensions`); + let content = compartments.get(ext.compartment) || ext.inner; + newCompartments.set(ext.compartment, content); + inner(content, prec); + } + else if (ext instanceof PrecExtension) { + inner(ext.inner, ext.prec); + } + else if (ext instanceof StateField) { + result[prec].push(ext); + if (ext.provides) + inner(ext.provides, prec); + } + else if (ext instanceof FacetProvider) { + result[prec].push(ext); + if (ext.facet.extensions) + inner(ext.facet.extensions, prec); + } + else { + let content = ext.extension; + if (!content) + throw new Error(`Unrecognized extension value in extension set (${ext}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`); + inner(content, prec); + } + } + inner(extension, Prec_.default); + return result.reduce((a, b) => a.concat(b)); + } + function ensureAddr(state, addr) { + if (addr & 1) + return 2 /* Computed */; + let idx = addr >> 1; + let status = state.status[idx]; + if (status == 4 /* Computing */) + throw new Error("Cyclic dependency between fields and/or facets"); + if (status & 2 /* Computed */) + return status; + state.status[idx] = 4 /* Computing */; + let changed = state.computeSlot(state, state.config.dynamicSlots[idx]); + return state.status[idx] = 2 /* Computed */ | changed; + } + function getAddr(state, addr) { + return addr & 1 ? state.config.staticValues[addr >> 1] : state.values[addr >> 1]; + } + + const languageData = /*@__PURE__*/Facet.define(); + const allowMultipleSelections = /*@__PURE__*/Facet.define({ + combine: values => values.some(v => v), + static: true + }); + const lineSeparator = /*@__PURE__*/Facet.define({ + combine: values => values.length ? values[0] : undefined, + static: true + }); + const changeFilter = /*@__PURE__*/Facet.define(); + const transactionFilter = /*@__PURE__*/Facet.define(); + const transactionExtender = /*@__PURE__*/Facet.define(); + const readOnly = /*@__PURE__*/Facet.define({ + combine: values => values.length ? values[0] : false + }); + + /** + Annotations are tagged values that are used to add metadata to + transactions in an extensible way. They should be used to model + things that effect the entire transaction (such as its [time + stamp](https://codemirror.net/6/docs/ref/#state.Transaction^time) or information about its + [origin](https://codemirror.net/6/docs/ref/#state.Transaction^userEvent)). For effects that happen + _alongside_ the other changes made by the transaction, [state + effects](https://codemirror.net/6/docs/ref/#state.StateEffect) are more appropriate. + */ + class Annotation { + /** + @internal + */ + constructor( + /** + The annotation type. + */ + type, + /** + The value of this annotation. + */ + value) { + this.type = type; + this.value = value; + } + /** + Define a new type of annotation. + */ + static define() { return new AnnotationType(); } + } + /** + Marker that identifies a type of [annotation](https://codemirror.net/6/docs/ref/#state.Annotation). + */ + class AnnotationType { + /** + Create an instance of this annotation. + */ + of(value) { return new Annotation(this, value); } + } + /** + Representation of a type of state effect. Defined with + [`StateEffect.define`](https://codemirror.net/6/docs/ref/#state.StateEffect^define). + */ + class StateEffectType { + /** + @internal + */ + constructor( + // The `any` types in these function types are there to work + // around TypeScript issue #37631, where the type guard on + // `StateEffect.is` mysteriously stops working when these properly + // have type `Value`. + /** + @internal + */ + map) { + this.map = map; + } + /** + Create a [state effect](https://codemirror.net/6/docs/ref/#state.StateEffect) instance of this + type. + */ + of(value) { return new StateEffect(this, value); } + } + /** + State effects can be used to represent additional effects + associated with a [transaction](https://codemirror.net/6/docs/ref/#state.Transaction.effects). They + are often useful to model changes to custom [state + fields](https://codemirror.net/6/docs/ref/#state.StateField), when those changes aren't implicit in + document or selection changes. + */ + class StateEffect { + /** + @internal + */ + constructor( + /** + @internal + */ + type, + /** + The value of this effect. + */ + value) { + this.type = type; + this.value = value; + } + /** + Map this effect through a position mapping. Will return + `undefined` when that ends up deleting the effect. + */ + map(mapping) { + let mapped = this.type.map(this.value, mapping); + return mapped === undefined ? undefined : mapped == this.value ? this : new StateEffect(this.type, mapped); + } + /** + Tells you whether this effect object is of a given + [type](https://codemirror.net/6/docs/ref/#state.StateEffectType). + */ + is(type) { return this.type == type; } + /** + Define a new effect type. The type parameter indicates the type + of values that his effect holds. + */ + static define(spec = {}) { + return new StateEffectType(spec.map || (v => v)); + } + /** + Map an array of effects through a change set. + */ + static mapEffects(effects, mapping) { + if (!effects.length) + return effects; + let result = []; + for (let effect of effects) { + let mapped = effect.map(mapping); + if (mapped) + result.push(mapped); + } + return result; + } + } + /** + This effect can be used to reconfigure the root extensions of + the editor. Doing this will discard any extensions + [appended](https://codemirror.net/6/docs/ref/#state.StateEffect^appendConfig), but does not reset + the content of [reconfigured](https://codemirror.net/6/docs/ref/#state.Compartment.reconfigure) + compartments. + */ + StateEffect.reconfigure = /*@__PURE__*/StateEffect.define(); + /** + Append extensions to the top-level configuration of the editor. + */ + StateEffect.appendConfig = /*@__PURE__*/StateEffect.define(); + /** + Changes to the editor state are grouped into transactions. + Typically, a user action creates a single transaction, which may + contain any number of document changes, may change the selection, + or have other effects. Create a transaction by calling + [`EditorState.update`](https://codemirror.net/6/docs/ref/#state.EditorState.update), or immediately + dispatch one by calling + [`EditorView.dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch). + */ + class Transaction { + constructor( + /** + The state from which the transaction starts. + */ + startState, + /** + The document changes made by this transaction. + */ + changes, + /** + The selection set by this transaction, or undefined if it + doesn't explicitly set a selection. + */ + selection, + /** + The effects added to the transaction. + */ + effects, + /** + @internal + */ + annotations, + /** + Whether the selection should be scrolled into view after this + transaction is dispatched. + */ + scrollIntoView) { + this.startState = startState; + this.changes = changes; + this.selection = selection; + this.effects = effects; + this.annotations = annotations; + this.scrollIntoView = scrollIntoView; + /** + @internal + */ + this._doc = null; + /** + @internal + */ + this._state = null; + if (selection) + checkSelection(selection, changes.newLength); + if (!annotations.some((a) => a.type == Transaction.time)) + this.annotations = annotations.concat(Transaction.time.of(Date.now())); + } + /** + @internal + */ + static create(startState, changes, selection, effects, annotations, scrollIntoView) { + return new Transaction(startState, changes, selection, effects, annotations, scrollIntoView); + } + /** + The new document produced by the transaction. Contrary to + [`.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state)`.doc`, accessing this won't + force the entire new state to be computed right away, so it is + recommended that [transaction + filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) use this getter + when they need to look at the new document. + */ + get newDoc() { + return this._doc || (this._doc = this.changes.apply(this.startState.doc)); + } + /** + The new selection produced by the transaction. If + [`this.selection`](https://codemirror.net/6/docs/ref/#state.Transaction.selection) is undefined, + this will [map](https://codemirror.net/6/docs/ref/#state.EditorSelection.map) the start state's + current selection through the changes made by the transaction. + */ + get newSelection() { + return this.selection || this.startState.selection.map(this.changes); + } + /** + The new state created by the transaction. Computed on demand + (but retained for subsequent access), so it is recommended not to + access it in [transaction + filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) when possible. + */ + get state() { + if (!this._state) + this.startState.applyTransaction(this); + return this._state; + } + /** + Get the value of the given annotation type, if any. + */ + annotation(type) { + for (let ann of this.annotations) + if (ann.type == type) + return ann.value; + return undefined; + } + /** + Indicates whether the transaction changed the document. + */ + get docChanged() { return !this.changes.empty; } + /** + Indicates whether this transaction reconfigures the state + (through a [configuration compartment](https://codemirror.net/6/docs/ref/#state.Compartment) or + with a top-level configuration + [effect](https://codemirror.net/6/docs/ref/#state.StateEffect^reconfigure). + */ + get reconfigured() { return this.startState.config != this.state.config; } + /** + Returns true if the transaction has a [user + event](https://codemirror.net/6/docs/ref/#state.Transaction^userEvent) annotation that is equal to + or more specific than `event`. For example, if the transaction + has `"select.pointer"` as user event, `"select"` and + `"select.pointer"` will match it. + */ + isUserEvent(event) { + let e = this.annotation(Transaction.userEvent); + return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == ".")); + } + } + /** + Annotation used to store transaction timestamps. Automatically + added to every transaction, holding `Date.now()`. + */ + Transaction.time = /*@__PURE__*/Annotation.define(); + /** + Annotation used to associate a transaction with a user interface + event. Holds a string identifying the event, using a + dot-separated format to support attaching more specific + information. The events used by the core libraries are: + + - `"input"` when content is entered + - `"input.type"` for typed input + - `"input.type.compose"` for composition + - `"input.paste"` for pasted input + - `"input.drop"` when adding content with drag-and-drop + - `"input.complete"` when autocompleting + - `"delete"` when the user deletes content + - `"delete.selection"` when deleting the selection + - `"delete.forward"` when deleting forward from the selection + - `"delete.backward"` when deleting backward from the selection + - `"delete.cut"` when cutting to the clipboard + - `"move"` when content is moved + - `"move.drop"` when content is moved within the editor through drag-and-drop + - `"select"` when explicitly changing the selection + - `"select.pointer"` when selecting with a mouse or other pointing device + - `"undo"` and `"redo"` for history actions + + Use [`isUserEvent`](https://codemirror.net/6/docs/ref/#state.Transaction.isUserEvent) to check + whether the annotation matches a given event. + */ + Transaction.userEvent = /*@__PURE__*/Annotation.define(); + /** + Annotation indicating whether a transaction should be added to + the undo history or not. + */ + Transaction.addToHistory = /*@__PURE__*/Annotation.define(); + /** + Annotation indicating (when present and true) that a transaction + represents a change made by some other actor, not the user. This + is used, for example, to tag other people's changes in + collaborative editing. + */ + Transaction.remote = /*@__PURE__*/Annotation.define(); + function joinRanges(a, b) { + let result = []; + for (let iA = 0, iB = 0;;) { + let from, to; + if (iA < a.length && (iB == b.length || b[iB] >= a[iA])) { + from = a[iA++]; + to = a[iA++]; + } + else if (iB < b.length) { + from = b[iB++]; + to = b[iB++]; + } + else + return result; + if (!result.length || result[result.length - 1] < from) + result.push(from, to); + else if (result[result.length - 1] < to) + result[result.length - 1] = to; + } + } + function mergeTransaction(a, b, sequential) { + var _a; + let mapForA, mapForB, changes; + if (sequential) { + mapForA = b.changes; + mapForB = ChangeSet.empty(b.changes.length); + changes = a.changes.compose(b.changes); + } + else { + mapForA = b.changes.map(a.changes); + mapForB = a.changes.mapDesc(b.changes, true); + changes = a.changes.compose(mapForA); + } + return { + changes, + selection: b.selection ? b.selection.map(mapForB) : (_a = a.selection) === null || _a === void 0 ? void 0 : _a.map(mapForA), + effects: StateEffect.mapEffects(a.effects, mapForA).concat(StateEffect.mapEffects(b.effects, mapForB)), + annotations: a.annotations.length ? a.annotations.concat(b.annotations) : b.annotations, + scrollIntoView: a.scrollIntoView || b.scrollIntoView + }; + } + function resolveTransactionInner(state, spec, docSize) { + let sel = spec.selection, annotations = asArray$1(spec.annotations); + if (spec.userEvent) + annotations = annotations.concat(Transaction.userEvent.of(spec.userEvent)); + return { + changes: spec.changes instanceof ChangeSet ? spec.changes + : ChangeSet.of(spec.changes || [], docSize, state.facet(lineSeparator)), + selection: sel && (sel instanceof EditorSelection ? sel : EditorSelection.single(sel.anchor, sel.head)), + effects: asArray$1(spec.effects), + annotations, + scrollIntoView: !!spec.scrollIntoView + }; + } + function resolveTransaction(state, specs, filter) { + let s = resolveTransactionInner(state, specs.length ? specs[0] : {}, state.doc.length); + if (specs.length && specs[0].filter === false) + filter = false; + for (let i = 1; i < specs.length; i++) { + if (specs[i].filter === false) + filter = false; + let seq = !!specs[i].sequential; + s = mergeTransaction(s, resolveTransactionInner(state, specs[i], seq ? s.changes.newLength : state.doc.length), seq); + } + let tr = Transaction.create(state, s.changes, s.selection, s.effects, s.annotations, s.scrollIntoView); + return extendTransaction(filter ? filterTransaction(tr) : tr); + } + // Finish a transaction by applying filters if necessary. + function filterTransaction(tr) { + let state = tr.startState; + // Change filters + let result = true; + for (let filter of state.facet(changeFilter)) { + let value = filter(tr); + if (value === false) { + result = false; + break; + } + if (Array.isArray(value)) + result = result === true ? value : joinRanges(result, value); + } + if (result !== true) { + let changes, back; + if (result === false) { + back = tr.changes.invertedDesc; + changes = ChangeSet.empty(state.doc.length); + } + else { + let filtered = tr.changes.filter(result); + changes = filtered.changes; + back = filtered.filtered.mapDesc(filtered.changes).invertedDesc; + } + tr = Transaction.create(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView); + } + // Transaction filters + let filters = state.facet(transactionFilter); + for (let i = filters.length - 1; i >= 0; i--) { + let filtered = filters[i](tr); + if (filtered instanceof Transaction) + tr = filtered; + else if (Array.isArray(filtered) && filtered.length == 1 && filtered[0] instanceof Transaction) + tr = filtered[0]; + else + tr = resolveTransaction(state, asArray$1(filtered), false); + } + return tr; + } + function extendTransaction(tr) { + let state = tr.startState, extenders = state.facet(transactionExtender), spec = tr; + for (let i = extenders.length - 1; i >= 0; i--) { + let extension = extenders[i](tr); + if (extension && Object.keys(extension).length) + spec = mergeTransaction(tr, resolveTransactionInner(state, extension, tr.changes.newLength), true); + } + return spec == tr ? tr : Transaction.create(state, tr.changes, tr.selection, spec.effects, spec.annotations, spec.scrollIntoView); + } + const none$2 = []; + function asArray$1(value) { + return value == null ? none$2 : Array.isArray(value) ? value : [value]; + } + + /** + The categories produced by a [character + categorizer](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer). These are used + do things like selecting by word. + */ + var CharCategory = /*@__PURE__*/(function (CharCategory) { + /** + Word characters. + */ + CharCategory[CharCategory["Word"] = 0] = "Word"; + /** + Whitespace. + */ + CharCategory[CharCategory["Space"] = 1] = "Space"; + /** + Anything else. + */ + CharCategory[CharCategory["Other"] = 2] = "Other"; + return CharCategory})(CharCategory || (CharCategory = {})); + const nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + let wordChar; + try { + wordChar = /*@__PURE__*/new RegExp("[\\p{Alphabetic}\\p{Number}_]", "u"); + } + catch (_) { } + function hasWordChar(str) { + if (wordChar) + return wordChar.test(str); + for (let i = 0; i < str.length; i++) { + let ch = str[i]; + if (/\w/.test(ch) || ch > "\x80" && (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))) + return true; + } + return false; + } + function makeCategorizer(wordChars) { + return (char) => { + if (!/\S/.test(char)) + return CharCategory.Space; + if (hasWordChar(char)) + return CharCategory.Word; + for (let i = 0; i < wordChars.length; i++) + if (char.indexOf(wordChars[i]) > -1) + return CharCategory.Word; + return CharCategory.Other; + }; + } + + /** + The editor state class is a persistent (immutable) data structure. + To update a state, you [create](https://codemirror.net/6/docs/ref/#state.EditorState.update) a + [transaction](https://codemirror.net/6/docs/ref/#state.Transaction), which produces a _new_ state + instance, without modifying the original object. + + As such, _never_ mutate properties of a state directly. That'll + just break things. + */ + class EditorState { + constructor( + /** + @internal + */ + config, + /** + The current document. + */ + doc, + /** + The current selection. + */ + selection, + /** + @internal + */ + values, computeSlot, tr) { + this.config = config; + this.doc = doc; + this.selection = selection; + this.values = values; + this.status = config.statusTemplate.slice(); + this.computeSlot = computeSlot; + // Fill in the computed state immediately, so that further queries + // for it made during the update return this state + if (tr) + tr._state = this; + for (let i = 0; i < this.config.dynamicSlots.length; i++) + ensureAddr(this, i << 1); + this.computeSlot = null; + } + field(field, require = true) { + let addr = this.config.address[field.id]; + if (addr == null) { + if (require) + throw new RangeError("Field is not present in this state"); + return undefined; + } + ensureAddr(this, addr); + return getAddr(this, addr); + } + /** + Create a [transaction](https://codemirror.net/6/docs/ref/#state.Transaction) that updates this + state. Any number of [transaction specs](https://codemirror.net/6/docs/ref/#state.TransactionSpec) + can be passed. Unless + [`sequential`](https://codemirror.net/6/docs/ref/#state.TransactionSpec.sequential) is set, the + [changes](https://codemirror.net/6/docs/ref/#state.TransactionSpec.changes) (if any) of each spec + are assumed to start in the _current_ document (not the document + produced by previous specs), and its + [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection) and + [effects](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) are assumed to refer + to the document created by its _own_ changes. The resulting + transaction contains the combined effect of all the different + specs. For [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection), later + specs take precedence over earlier ones. + */ + update(...specs) { + return resolveTransaction(this, specs, true); + } + /** + @internal + */ + applyTransaction(tr) { + let conf = this.config, { base, compartments } = conf; + for (let effect of tr.effects) { + if (effect.is(Compartment.reconfigure)) { + if (conf) { + compartments = new Map; + conf.compartments.forEach((val, key) => compartments.set(key, val)); + conf = null; + } + compartments.set(effect.value.compartment, effect.value.extension); + } + else if (effect.is(StateEffect.reconfigure)) { + conf = null; + base = effect.value; + } + else if (effect.is(StateEffect.appendConfig)) { + conf = null; + base = asArray$1(base).concat(effect.value); + } + } + let startValues; + if (!conf) { + conf = Configuration.resolve(base, compartments, this); + let intermediateState = new EditorState(conf, this.doc, this.selection, conf.dynamicSlots.map(() => null), (state, slot) => slot.reconfigure(state, this), null); + startValues = intermediateState.values; + } + else { + startValues = tr.startState.values.slice(); + } + new EditorState(conf, tr.newDoc, tr.newSelection, startValues, (state, slot) => slot.update(state, tr), tr); + } + /** + Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that + replaces every selection range with the given content. + */ + replaceSelection(text) { + if (typeof text == "string") + text = this.toText(text); + return this.changeByRange(range => ({ changes: { from: range.from, to: range.to, insert: text }, + range: EditorSelection.cursor(range.from + text.length) })); + } + /** + Create a set of changes and a new selection by running the given + function for each range in the active selection. The function + can return an optional set of changes (in the coordinate space + of the start document), plus an updated range (in the coordinate + space of the document produced by the call's own changes). This + method will merge all the changes and ranges into a single + changeset and selection, and return it as a [transaction + spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec), which can be passed to + [`update`](https://codemirror.net/6/docs/ref/#state.EditorState.update). + */ + changeByRange(f) { + let sel = this.selection; + let result1 = f(sel.ranges[0]); + let changes = this.changes(result1.changes), ranges = [result1.range]; + let effects = asArray$1(result1.effects); + for (let i = 1; i < sel.ranges.length; i++) { + let result = f(sel.ranges[i]); + let newChanges = this.changes(result.changes), newMapped = newChanges.map(changes); + for (let j = 0; j < i; j++) + ranges[j] = ranges[j].map(newMapped); + let mapBy = changes.mapDesc(newChanges, true); + ranges.push(result.range.map(mapBy)); + changes = changes.compose(newMapped); + effects = StateEffect.mapEffects(effects, newMapped).concat(StateEffect.mapEffects(asArray$1(result.effects), mapBy)); + } + return { + changes, + selection: EditorSelection.create(ranges, sel.mainIndex), + effects + }; + } + /** + Create a [change set](https://codemirror.net/6/docs/ref/#state.ChangeSet) from the given change + description, taking the state's document length and line + separator into account. + */ + changes(spec = []) { + if (spec instanceof ChangeSet) + return spec; + return ChangeSet.of(spec, this.doc.length, this.facet(EditorState.lineSeparator)); + } + /** + Using the state's [line + separator](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator), create a + [`Text`](https://codemirror.net/6/docs/ref/#state.Text) instance from the given string. + */ + toText(string) { + return Text.of(string.split(this.facet(EditorState.lineSeparator) || DefaultSplit)); + } + /** + Return the given range of the document as a string. + */ + sliceDoc(from = 0, to = this.doc.length) { + return this.doc.sliceString(from, to, this.lineBreak); + } + /** + Get the value of a state [facet](https://codemirror.net/6/docs/ref/#state.Facet). + */ + facet(facet) { + let addr = this.config.address[facet.id]; + if (addr == null) + return facet.default; + ensureAddr(this, addr); + return getAddr(this, addr); + } + /** + Convert this state to a JSON-serializable object. When custom + fields should be serialized, you can pass them in as an object + mapping property names (in the resulting object, which should + not use `doc` or `selection`) to fields. + */ + toJSON(fields) { + let result = { + doc: this.sliceDoc(), + selection: this.selection.toJSON() + }; + if (fields) + for (let prop in fields) { + let value = fields[prop]; + if (value instanceof StateField) + result[prop] = value.spec.toJSON(this.field(fields[prop]), this); + } + return result; + } + /** + Deserialize a state from its JSON representation. When custom + fields should be deserialized, pass the same object you passed + to [`toJSON`](https://codemirror.net/6/docs/ref/#state.EditorState.toJSON) when serializing as + third argument. + */ + static fromJSON(json, config = {}, fields) { + if (!json || typeof json.doc != "string") + throw new RangeError("Invalid JSON representation for EditorState"); + let fieldInit = []; + if (fields) + for (let prop in fields) { + let field = fields[prop], value = json[prop]; + fieldInit.push(field.init(state => field.spec.fromJSON(value, state))); + } + return EditorState.create({ + doc: json.doc, + selection: EditorSelection.fromJSON(json.selection), + extensions: config.extensions ? fieldInit.concat([config.extensions]) : fieldInit + }); + } + /** + Create a new state. You'll usually only need this when + initializing an editor—updated states are created by applying + transactions. + */ + static create(config = {}) { + let configuration = Configuration.resolve(config.extensions || [], new Map); + let doc = config.doc instanceof Text ? config.doc + : Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit)); + let selection = !config.selection ? EditorSelection.single(0) + : config.selection instanceof EditorSelection ? config.selection + : EditorSelection.single(config.selection.anchor, config.selection.head); + checkSelection(selection, doc.length); + if (!configuration.staticFacet(allowMultipleSelections)) + selection = selection.asSingle(); + return new EditorState(configuration, doc, selection, configuration.dynamicSlots.map(() => null), (state, slot) => slot.create(state), null); + } + /** + The size (in columns) of a tab in the document, determined by + the [`tabSize`](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize) facet. + */ + get tabSize() { return this.facet(EditorState.tabSize); } + /** + Get the proper [line-break](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator) + string for this state. + */ + get lineBreak() { return this.facet(EditorState.lineSeparator) || "\n"; } + /** + Returns true when the editor is + [configured](https://codemirror.net/6/docs/ref/#state.EditorState^readOnly) to be read-only. + */ + get readOnly() { return this.facet(readOnly); } + /** + Look up a translation for the given phrase (via the + [`phrases`](https://codemirror.net/6/docs/ref/#state.EditorState^phrases) facet), or return the + original string if no translation is found. + + If additional arguments are passed, they will be inserted in + place of markers like `$1` (for the first value) and `$2`, etc. + A single `$` is equivalent to `$1`, and `$$` will produce a + literal dollar sign. + */ + phrase(phrase, ...insert) { + for (let map of this.facet(EditorState.phrases)) + if (Object.prototype.hasOwnProperty.call(map, phrase)) { + phrase = map[phrase]; + break; + } + if (insert.length) + phrase = phrase.replace(/\$(\$|\d*)/g, (m, i) => { + if (i == "$") + return "$"; + let n = +(i || 1); + return !n || n > insert.length ? m : insert[n - 1]; + }); + return phrase; + } + /** + Find the values for a given language data field, provided by the + the [`languageData`](https://codemirror.net/6/docs/ref/#state.EditorState^languageData) facet. + */ + languageDataAt(name, pos, side = -1) { + let values = []; + for (let provider of this.facet(languageData)) { + for (let result of provider(this, pos, side)) { + if (Object.prototype.hasOwnProperty.call(result, name)) + values.push(result[name]); + } + } + return values; + } + /** + Return a function that can categorize strings (expected to + represent a single [grapheme cluster](https://codemirror.net/6/docs/ref/#state.findClusterBreak)) + into one of: + + - Word (contains an alphanumeric character or a character + explicitly listed in the local language's `"wordChars"` + language data, which should be a string) + - Space (contains only whitespace) + - Other (anything else) + */ + charCategorizer(at) { + return makeCategorizer(this.languageDataAt("wordChars", at).join("")); + } + /** + Find the word at the given position, meaning the range + containing all [word](https://codemirror.net/6/docs/ref/#state.CharCategory.Word) characters + around it. If no word characters are adjacent to the position, + this returns null. + */ + wordAt(pos) { + let { text, from, length } = this.doc.lineAt(pos); + let cat = this.charCategorizer(pos); + let start = pos - from, end = pos - from; + while (start > 0) { + let prev = findClusterBreak(text, start, false); + if (cat(text.slice(prev, start)) != CharCategory.Word) + break; + start = prev; + } + while (end < length) { + let next = findClusterBreak(text, end); + if (cat(text.slice(end, next)) != CharCategory.Word) + break; + end = next; + } + return start == end ? null : EditorSelection.range(start + from, end + from); + } + } + /** + A facet that, when enabled, causes the editor to allow multiple + ranges to be selected. Be careful though, because by default the + editor relies on the native DOM selection, which cannot handle + multiple selections. An extension like + [`drawSelection`](https://codemirror.net/6/docs/ref/#view.drawSelection) can be used to make + secondary selections visible to the user. + */ + EditorState.allowMultipleSelections = allowMultipleSelections; + /** + Configures the tab size to use in this state. The first + (highest-precedence) value of the facet is used. If no value is + given, this defaults to 4. + */ + EditorState.tabSize = /*@__PURE__*/Facet.define({ + combine: values => values.length ? values[0] : 4 + }); + /** + The line separator to use. By default, any of `"\n"`, `"\r\n"` + and `"\r"` is treated as a separator when splitting lines, and + lines are joined with `"\n"`. + + When you configure a value here, only that precise separator + will be used, allowing you to round-trip documents through the + editor without normalizing line separators. + */ + EditorState.lineSeparator = lineSeparator; + /** + This facet controls the value of the + [`readOnly`](https://codemirror.net/6/docs/ref/#state.EditorState.readOnly) getter, which is + consulted by commands and extensions that implement editing + functionality to determine whether they should apply. It + defaults to false, but when its highest-precedence value is + `true`, such functionality disables itself. + + Not to be confused with + [`EditorView.editable`](https://codemirror.net/6/docs/ref/#view.EditorView^editable), which + controls whether the editor's DOM is set to be editable (and + thus focusable). + */ + EditorState.readOnly = readOnly; + /** + Registers translation phrases. The + [`phrase`](https://codemirror.net/6/docs/ref/#state.EditorState.phrase) method will look through + all objects registered with this facet to find translations for + its argument. + */ + EditorState.phrases = /*@__PURE__*/Facet.define({ + compare(a, b) { + let kA = Object.keys(a), kB = Object.keys(b); + return kA.length == kB.length && kA.every(k => a[k] == b[k]); + } + }); + /** + A facet used to register [language + data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) providers. + */ + EditorState.languageData = languageData; + /** + Facet used to register change filters, which are called for each + transaction (unless explicitly + [disabled](https://codemirror.net/6/docs/ref/#state.TransactionSpec.filter)), and can suppress + part of the transaction's changes. + + Such a function can return `true` to indicate that it doesn't + want to do anything, `false` to completely stop the changes in + the transaction, or a set of ranges in which changes should be + suppressed. Such ranges are represented as an array of numbers, + with each pair of two numbers indicating the start and end of a + range. So for example `[10, 20, 100, 110]` suppresses changes + between 10 and 20, and between 100 and 110. + */ + EditorState.changeFilter = changeFilter; + /** + Facet used to register a hook that gets a chance to update or + replace transaction specs before they are applied. This will + only be applied for transactions that don't have + [`filter`](https://codemirror.net/6/docs/ref/#state.TransactionSpec.filter) set to `false`. You + can either return a single transaction spec (possibly the input + transaction), or an array of specs (which will be combined in + the same way as the arguments to + [`EditorState.update`](https://codemirror.net/6/docs/ref/#state.EditorState.update)). + + When possible, it is recommended to avoid accessing + [`Transaction.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state) in a filter, + since it will force creation of a state that will then be + discarded again, if the transaction is actually filtered. + + (This functionality should be used with care. Indiscriminately + modifying transaction is likely to break something or degrade + the user experience.) + */ + EditorState.transactionFilter = transactionFilter; + /** + This is a more limited form of + [`transactionFilter`](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter), + which can only add + [annotations](https://codemirror.net/6/docs/ref/#state.TransactionSpec.annotations) and + [effects](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects). _But_, this type + of filter runs even if the transaction has disabled regular + [filtering](https://codemirror.net/6/docs/ref/#state.TransactionSpec.filter), making it suitable + for effects that don't need to touch the changes or selection, + but do want to process every transaction. + + Extenders run _after_ filters, when both are present. + */ + EditorState.transactionExtender = transactionExtender; + Compartment.reconfigure = /*@__PURE__*/StateEffect.define(); + + /** + Utility function for combining behaviors to fill in a config + object from an array of provided configs. `defaults` should hold + default values for all optional fields in `Config`. + + The function will, by default, error + when a field gets two values that aren't `===`-equal, but you can + provide combine functions per field to do something else. + */ + function combineConfig(configs, defaults, // Should hold only the optional properties of Config, but I haven't managed to express that + combine = {}) { + let result = {}; + for (let config of configs) + for (let key of Object.keys(config)) { + let value = config[key], current = result[key]; + if (current === undefined) + result[key] = value; + else if (current === value || value === undefined) ; // No conflict + else if (Object.hasOwnProperty.call(combine, key)) + result[key] = combine[key](current, value); + else + throw new Error("Config merge conflict for field " + key); + } + for (let key in defaults) + if (result[key] === undefined) + result[key] = defaults[key]; + return result; + } + + /** + Each range is associated with a value, which must inherit from + this class. + */ + class RangeValue { + /** + Compare this value with another value. Used when comparing + rangesets. The default implementation compares by identity. + Unless you are only creating a fixed number of unique instances + of your value type, it is a good idea to implement this + properly. + */ + eq(other) { return this == other; } + /** + Create a [range](https://codemirror.net/6/docs/ref/#state.Range) with this value. + */ + range(from, to = from) { return Range$1.create(from, to, this); } + } + RangeValue.prototype.startSide = RangeValue.prototype.endSide = 0; + RangeValue.prototype.point = false; + RangeValue.prototype.mapMode = MapMode.TrackDel; + /** + A range associates a value with a range of positions. + */ + class Range$1 { + constructor( + /** + The range's start position. + */ + from, + /** + Its end position. + */ + to, + /** + The value associated with this range. + */ + value) { + this.from = from; + this.to = to; + this.value = value; + } + /** + @internal + */ + static create(from, to, value) { + return new Range$1(from, to, value); + } + } + function cmpRange(a, b) { + return a.from - b.from || a.value.startSide - b.value.startSide; + } + class Chunk { + constructor(from, to, value, + // Chunks are marked with the largest point that occurs + // in them (or -1 for no points), so that scans that are + // only interested in points (such as the + // heightmap-related logic) can skip range-only chunks. + maxPoint) { + this.from = from; + this.to = to; + this.value = value; + this.maxPoint = maxPoint; + } + get length() { return this.to[this.to.length - 1]; } + // Find the index of the given position and side. Use the ranges' + // `from` pos when `end == false`, `to` when `end == true`. + findIndex(pos, side, end, startAt = 0) { + let arr = end ? this.to : this.from; + for (let lo = startAt, hi = arr.length;;) { + if (lo == hi) + return lo; + let mid = (lo + hi) >> 1; + let diff = arr[mid] - pos || (end ? this.value[mid].endSide : this.value[mid].startSide) - side; + if (mid == lo) + return diff >= 0 ? lo : hi; + if (diff >= 0) + hi = mid; + else + lo = mid + 1; + } + } + between(offset, from, to, f) { + for (let i = this.findIndex(from, -1000000000 /* Far */, true), e = this.findIndex(to, 1000000000 /* Far */, false, i); i < e; i++) + if (f(this.from[i] + offset, this.to[i] + offset, this.value[i]) === false) + return false; + } + map(offset, changes) { + let value = [], from = [], to = [], newPos = -1, maxPoint = -1; + for (let i = 0; i < this.value.length; i++) { + let val = this.value[i], curFrom = this.from[i] + offset, curTo = this.to[i] + offset, newFrom, newTo; + if (curFrom == curTo) { + let mapped = changes.mapPos(curFrom, val.startSide, val.mapMode); + if (mapped == null) + continue; + newFrom = newTo = mapped; + if (val.startSide != val.endSide) { + newTo = changes.mapPos(curFrom, val.endSide); + if (newTo < newFrom) + continue; + } + } + else { + newFrom = changes.mapPos(curFrom, val.startSide); + newTo = changes.mapPos(curTo, val.endSide); + if (newFrom > newTo || newFrom == newTo && val.startSide > 0 && val.endSide <= 0) + continue; + } + if ((newTo - newFrom || val.endSide - val.startSide) < 0) + continue; + if (newPos < 0) + newPos = newFrom; + if (val.point) + maxPoint = Math.max(maxPoint, newTo - newFrom); + value.push(val); + from.push(newFrom - newPos); + to.push(newTo - newPos); + } + return { mapped: value.length ? new Chunk(from, to, value, maxPoint) : null, pos: newPos }; + } + } + /** + A range set stores a collection of [ranges](https://codemirror.net/6/docs/ref/#state.Range) in a + way that makes them efficient to [map](https://codemirror.net/6/docs/ref/#state.RangeSet.map) and + [update](https://codemirror.net/6/docs/ref/#state.RangeSet.update). This is an immutable data + structure. + */ + class RangeSet { + constructor( + /** + @internal + */ + chunkPos, + /** + @internal + */ + chunk, + /** + @internal + */ + nextLayer, + /** + @internal + */ + maxPoint) { + this.chunkPos = chunkPos; + this.chunk = chunk; + this.nextLayer = nextLayer; + this.maxPoint = maxPoint; + } + /** + @internal + */ + static create(chunkPos, chunk, nextLayer, maxPoint) { + return new RangeSet(chunkPos, chunk, nextLayer, maxPoint); + } + /** + @internal + */ + get length() { + let last = this.chunk.length - 1; + return last < 0 ? 0 : Math.max(this.chunkEnd(last), this.nextLayer.length); + } + /** + The number of ranges in the set. + */ + get size() { + if (this.isEmpty) + return 0; + let size = this.nextLayer.size; + for (let chunk of this.chunk) + size += chunk.value.length; + return size; + } + /** + @internal + */ + chunkEnd(index) { + return this.chunkPos[index] + this.chunk[index].length; + } + /** + Update the range set, optionally adding new ranges or filtering + out existing ones. + + (Note: The type parameter is just there as a kludge to work + around TypeScript variance issues that prevented `RangeSet` + from being a subtype of `RangeSet` when `X` is a subtype of + `Y`.) + */ + update(updateSpec) { + let { add = [], sort = false, filterFrom = 0, filterTo = this.length } = updateSpec; + let filter = updateSpec.filter; + if (add.length == 0 && !filter) + return this; + if (sort) + add = add.slice().sort(cmpRange); + if (this.isEmpty) + return add.length ? RangeSet.of(add) : this; + let cur = new LayerCursor(this, null, -1).goto(0), i = 0, spill = []; + let builder = new RangeSetBuilder(); + while (cur.value || i < add.length) { + if (i < add.length && (cur.from - add[i].from || cur.startSide - add[i].value.startSide) >= 0) { + let range = add[i++]; + if (!builder.addInner(range.from, range.to, range.value)) + spill.push(range); + } + else if (cur.rangeIndex == 1 && cur.chunkIndex < this.chunk.length && + (i == add.length || this.chunkEnd(cur.chunkIndex) < add[i].from) && + (!filter || filterFrom > this.chunkEnd(cur.chunkIndex) || filterTo < this.chunkPos[cur.chunkIndex]) && + builder.addChunk(this.chunkPos[cur.chunkIndex], this.chunk[cur.chunkIndex])) { + cur.nextChunk(); + } + else { + if (!filter || filterFrom > cur.to || filterTo < cur.from || filter(cur.from, cur.to, cur.value)) { + if (!builder.addInner(cur.from, cur.to, cur.value)) + spill.push(Range$1.create(cur.from, cur.to, cur.value)); + } + cur.next(); + } + } + return builder.finishInner(this.nextLayer.isEmpty && !spill.length ? RangeSet.empty + : this.nextLayer.update({ add: spill, filter, filterFrom, filterTo })); + } + /** + Map this range set through a set of changes, return the new set. + */ + map(changes) { + if (changes.empty || this.isEmpty) + return this; + let chunks = [], chunkPos = [], maxPoint = -1; + for (let i = 0; i < this.chunk.length; i++) { + let start = this.chunkPos[i], chunk = this.chunk[i]; + let touch = changes.touchesRange(start, start + chunk.length); + if (touch === false) { + maxPoint = Math.max(maxPoint, chunk.maxPoint); + chunks.push(chunk); + chunkPos.push(changes.mapPos(start)); + } + else if (touch === true) { + let { mapped, pos } = chunk.map(start, changes); + if (mapped) { + maxPoint = Math.max(maxPoint, mapped.maxPoint); + chunks.push(mapped); + chunkPos.push(pos); + } + } + } + let next = this.nextLayer.map(changes); + return chunks.length == 0 ? next : new RangeSet(chunkPos, chunks, next || RangeSet.empty, maxPoint); + } + /** + Iterate over the ranges that touch the region `from` to `to`, + calling `f` for each. There is no guarantee that the ranges will + be reported in any specific order. When the callback returns + `false`, iteration stops. + */ + between(from, to, f) { + if (this.isEmpty) + return; + for (let i = 0; i < this.chunk.length; i++) { + let start = this.chunkPos[i], chunk = this.chunk[i]; + if (to >= start && from <= start + chunk.length && + chunk.between(start, from - start, to - start, f) === false) + return; + } + this.nextLayer.between(from, to, f); + } + /** + Iterate over the ranges in this set, in order, including all + ranges that end at or after `from`. + */ + iter(from = 0) { + return HeapCursor.from([this]).goto(from); + } + /** + @internal + */ + get isEmpty() { return this.nextLayer == this; } + /** + Iterate over the ranges in a collection of sets, in order, + starting from `from`. + */ + static iter(sets, from = 0) { + return HeapCursor.from(sets).goto(from); + } + /** + Iterate over two groups of sets, calling methods on `comparator` + to notify it of possible differences. + */ + static compare(oldSets, newSets, + /** + This indicates how the underlying data changed between these + ranges, and is needed to synchronize the iteration. `from` and + `to` are coordinates in the _new_ space, after these changes. + */ + textDiff, comparator, + /** + Can be used to ignore all non-point ranges, and points below + the given size. When -1, all ranges are compared. + */ + minPointSize = -1) { + let a = oldSets.filter(set => set.maxPoint > 0 || !set.isEmpty && set.maxPoint >= minPointSize); + let b = newSets.filter(set => set.maxPoint > 0 || !set.isEmpty && set.maxPoint >= minPointSize); + let sharedChunks = findSharedChunks(a, b, textDiff); + let sideA = new SpanCursor(a, sharedChunks, minPointSize); + let sideB = new SpanCursor(b, sharedChunks, minPointSize); + textDiff.iterGaps((fromA, fromB, length) => compare(sideA, fromA, sideB, fromB, length, comparator)); + if (textDiff.empty && textDiff.length == 0) + compare(sideA, 0, sideB, 0, 0, comparator); + } + /** + Compare the contents of two groups of range sets, returning true + if they are equivalent in the given range. + */ + static eq(oldSets, newSets, from = 0, to) { + if (to == null) + to = 1000000000 /* Far */; + let a = oldSets.filter(set => !set.isEmpty && newSets.indexOf(set) < 0); + let b = newSets.filter(set => !set.isEmpty && oldSets.indexOf(set) < 0); + if (a.length != b.length) + return false; + if (!a.length) + return true; + let sharedChunks = findSharedChunks(a, b); + let sideA = new SpanCursor(a, sharedChunks, 0).goto(from), sideB = new SpanCursor(b, sharedChunks, 0).goto(from); + for (;;) { + if (sideA.to != sideB.to || + !sameValues(sideA.active, sideB.active) || + sideA.point && (!sideB.point || !sideA.point.eq(sideB.point))) + return false; + if (sideA.to > to) + return true; + sideA.next(); + sideB.next(); + } + } + /** + Iterate over a group of range sets at the same time, notifying + the iterator about the ranges covering every given piece of + content. Returns the open count (see + [`SpanIterator.span`](https://codemirror.net/6/docs/ref/#state.SpanIterator.span)) at the end + of the iteration. + */ + static spans(sets, from, to, iterator, + /** + When given and greater than -1, only points of at least this + size are taken into account. + */ + minPointSize = -1) { + let cursor = new SpanCursor(sets, null, minPointSize).goto(from), pos = from; + let open = cursor.openStart; + for (;;) { + let curTo = Math.min(cursor.to, to); + if (cursor.point) { + iterator.point(pos, curTo, cursor.point, cursor.activeForPoint(cursor.to), open, cursor.pointRank); + open = cursor.openEnd(curTo) + (cursor.to > curTo ? 1 : 0); + } + else if (curTo > pos) { + iterator.span(pos, curTo, cursor.active, open); + open = cursor.openEnd(curTo); + } + if (cursor.to > to) + break; + pos = cursor.to; + cursor.next(); + } + return open; + } + /** + Create a range set for the given range or array of ranges. By + default, this expects the ranges to be _sorted_ (by start + position and, if two start at the same position, + `value.startSide`). You can pass `true` as second argument to + cause the method to sort them. + */ + static of(ranges, sort = false) { + let build = new RangeSetBuilder(); + for (let range of ranges instanceof Range$1 ? [ranges] : sort ? lazySort(ranges) : ranges) + build.add(range.from, range.to, range.value); + return build.finish(); + } + } + /** + The empty set of ranges. + */ + RangeSet.empty = /*@__PURE__*/new RangeSet([], [], null, -1); + function lazySort(ranges) { + if (ranges.length > 1) + for (let prev = ranges[0], i = 1; i < ranges.length; i++) { + let cur = ranges[i]; + if (cmpRange(prev, cur) > 0) + return ranges.slice().sort(cmpRange); + prev = cur; + } + return ranges; + } + RangeSet.empty.nextLayer = RangeSet.empty; + /** + A range set builder is a data structure that helps build up a + [range set](https://codemirror.net/6/docs/ref/#state.RangeSet) directly, without first allocating + an array of [`Range`](https://codemirror.net/6/docs/ref/#state.Range) objects. + */ + class RangeSetBuilder { + /** + Create an empty builder. + */ + constructor() { + this.chunks = []; + this.chunkPos = []; + this.chunkStart = -1; + this.last = null; + this.lastFrom = -1000000000 /* Far */; + this.lastTo = -1000000000 /* Far */; + this.from = []; + this.to = []; + this.value = []; + this.maxPoint = -1; + this.setMaxPoint = -1; + this.nextLayer = null; + } + finishChunk(newArrays) { + this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint)); + this.chunkPos.push(this.chunkStart); + this.chunkStart = -1; + this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint); + this.maxPoint = -1; + if (newArrays) { + this.from = []; + this.to = []; + this.value = []; + } + } + /** + Add a range. Ranges should be added in sorted (by `from` and + `value.startSide`) order. + */ + add(from, to, value) { + if (!this.addInner(from, to, value)) + (this.nextLayer || (this.nextLayer = new RangeSetBuilder)).add(from, to, value); + } + /** + @internal + */ + addInner(from, to, value) { + let diff = from - this.lastTo || value.startSide - this.last.endSide; + if (diff <= 0 && (from - this.lastFrom || value.startSide - this.last.startSide) < 0) + throw new Error("Ranges must be added sorted by `from` position and `startSide`"); + if (diff < 0) + return false; + if (this.from.length == 250 /* ChunkSize */) + this.finishChunk(true); + if (this.chunkStart < 0) + this.chunkStart = from; + this.from.push(from - this.chunkStart); + this.to.push(to - this.chunkStart); + this.last = value; + this.lastFrom = from; + this.lastTo = to; + this.value.push(value); + if (value.point) + this.maxPoint = Math.max(this.maxPoint, to - from); + return true; + } + /** + @internal + */ + addChunk(from, chunk) { + if ((from - this.lastTo || chunk.value[0].startSide - this.last.endSide) < 0) + return false; + if (this.from.length) + this.finishChunk(true); + this.setMaxPoint = Math.max(this.setMaxPoint, chunk.maxPoint); + this.chunks.push(chunk); + this.chunkPos.push(from); + let last = chunk.value.length - 1; + this.last = chunk.value[last]; + this.lastFrom = chunk.from[last] + from; + this.lastTo = chunk.to[last] + from; + return true; + } + /** + Finish the range set. Returns the new set. The builder can't be + used anymore after this has been called. + */ + finish() { return this.finishInner(RangeSet.empty); } + /** + @internal + */ + finishInner(next) { + if (this.from.length) + this.finishChunk(false); + if (this.chunks.length == 0) + return next; + let result = RangeSet.create(this.chunkPos, this.chunks, this.nextLayer ? this.nextLayer.finishInner(next) : next, this.setMaxPoint); + this.from = null; // Make sure further `add` calls produce errors + return result; + } + } + function findSharedChunks(a, b, textDiff) { + let inA = new Map(); + for (let set of a) + for (let i = 0; i < set.chunk.length; i++) + if (set.chunk[i].maxPoint <= 0) + inA.set(set.chunk[i], set.chunkPos[i]); + let shared = new Set(); + for (let set of b) + for (let i = 0; i < set.chunk.length; i++) { + let known = inA.get(set.chunk[i]); + if (known != null && (textDiff ? textDiff.mapPos(known) : known) == set.chunkPos[i] && + !(textDiff === null || textDiff === void 0 ? void 0 : textDiff.touchesRange(known, known + set.chunk[i].length))) + shared.add(set.chunk[i]); + } + return shared; + } + class LayerCursor { + constructor(layer, skip, minPoint, rank = 0) { + this.layer = layer; + this.skip = skip; + this.minPoint = minPoint; + this.rank = rank; + } + get startSide() { return this.value ? this.value.startSide : 0; } + get endSide() { return this.value ? this.value.endSide : 0; } + goto(pos, side = -1000000000 /* Far */) { + this.chunkIndex = this.rangeIndex = 0; + this.gotoInner(pos, side, false); + return this; + } + gotoInner(pos, side, forward) { + while (this.chunkIndex < this.layer.chunk.length) { + let next = this.layer.chunk[this.chunkIndex]; + if (!(this.skip && this.skip.has(next) || + this.layer.chunkEnd(this.chunkIndex) < pos || + next.maxPoint < this.minPoint)) + break; + this.chunkIndex++; + forward = false; + } + if (this.chunkIndex < this.layer.chunk.length) { + let rangeIndex = this.layer.chunk[this.chunkIndex].findIndex(pos - this.layer.chunkPos[this.chunkIndex], side, true); + if (!forward || this.rangeIndex < rangeIndex) + this.setRangeIndex(rangeIndex); + } + this.next(); + } + forward(pos, side) { + if ((this.to - pos || this.endSide - side) < 0) + this.gotoInner(pos, side, true); + } + next() { + for (;;) { + if (this.chunkIndex == this.layer.chunk.length) { + this.from = this.to = 1000000000 /* Far */; + this.value = null; + break; + } + else { + let chunkPos = this.layer.chunkPos[this.chunkIndex], chunk = this.layer.chunk[this.chunkIndex]; + let from = chunkPos + chunk.from[this.rangeIndex]; + this.from = from; + this.to = chunkPos + chunk.to[this.rangeIndex]; + this.value = chunk.value[this.rangeIndex]; + this.setRangeIndex(this.rangeIndex + 1); + if (this.minPoint < 0 || this.value.point && this.to - this.from >= this.minPoint) + break; + } + } + } + setRangeIndex(index) { + if (index == this.layer.chunk[this.chunkIndex].value.length) { + this.chunkIndex++; + if (this.skip) { + while (this.chunkIndex < this.layer.chunk.length && this.skip.has(this.layer.chunk[this.chunkIndex])) + this.chunkIndex++; + } + this.rangeIndex = 0; + } + else { + this.rangeIndex = index; + } + } + nextChunk() { + this.chunkIndex++; + this.rangeIndex = 0; + this.next(); + } + compare(other) { + return this.from - other.from || this.startSide - other.startSide || this.rank - other.rank || + this.to - other.to || this.endSide - other.endSide; + } + } + class HeapCursor { + constructor(heap) { + this.heap = heap; + } + static from(sets, skip = null, minPoint = -1) { + let heap = []; + for (let i = 0; i < sets.length; i++) { + for (let cur = sets[i]; !cur.isEmpty; cur = cur.nextLayer) { + if (cur.maxPoint >= minPoint) + heap.push(new LayerCursor(cur, skip, minPoint, i)); + } + } + return heap.length == 1 ? heap[0] : new HeapCursor(heap); + } + get startSide() { return this.value ? this.value.startSide : 0; } + goto(pos, side = -1000000000 /* Far */) { + for (let cur of this.heap) + cur.goto(pos, side); + for (let i = this.heap.length >> 1; i >= 0; i--) + heapBubble(this.heap, i); + this.next(); + return this; + } + forward(pos, side) { + for (let cur of this.heap) + cur.forward(pos, side); + for (let i = this.heap.length >> 1; i >= 0; i--) + heapBubble(this.heap, i); + if ((this.to - pos || this.value.endSide - side) < 0) + this.next(); + } + next() { + if (this.heap.length == 0) { + this.from = this.to = 1000000000 /* Far */; + this.value = null; + this.rank = -1; + } + else { + let top = this.heap[0]; + this.from = top.from; + this.to = top.to; + this.value = top.value; + this.rank = top.rank; + if (top.value) + top.next(); + heapBubble(this.heap, 0); + } + } + } + function heapBubble(heap, index) { + for (let cur = heap[index];;) { + let childIndex = (index << 1) + 1; + if (childIndex >= heap.length) + break; + let child = heap[childIndex]; + if (childIndex + 1 < heap.length && child.compare(heap[childIndex + 1]) >= 0) { + child = heap[childIndex + 1]; + childIndex++; + } + if (cur.compare(child) < 0) + break; + heap[childIndex] = cur; + heap[index] = child; + index = childIndex; + } + } + class SpanCursor { + constructor(sets, skip, minPoint) { + this.minPoint = minPoint; + this.active = []; + this.activeTo = []; + this.activeRank = []; + this.minActive = -1; + // A currently active point range, if any + this.point = null; + this.pointFrom = 0; + this.pointRank = 0; + this.to = -1000000000 /* Far */; + this.endSide = 0; + this.openStart = -1; + this.cursor = HeapCursor.from(sets, skip, minPoint); + } + goto(pos, side = -1000000000 /* Far */) { + this.cursor.goto(pos, side); + this.active.length = this.activeTo.length = this.activeRank.length = 0; + this.minActive = -1; + this.to = pos; + this.endSide = side; + this.openStart = -1; + this.next(); + return this; + } + forward(pos, side) { + while (this.minActive > -1 && (this.activeTo[this.minActive] - pos || this.active[this.minActive].endSide - side) < 0) + this.removeActive(this.minActive); + this.cursor.forward(pos, side); + } + removeActive(index) { + remove(this.active, index); + remove(this.activeTo, index); + remove(this.activeRank, index); + this.minActive = findMinIndex(this.active, this.activeTo); + } + addActive(trackOpen) { + let i = 0, { value, to, rank } = this.cursor; + while (i < this.activeRank.length && this.activeRank[i] <= rank) + i++; + insert(this.active, i, value); + insert(this.activeTo, i, to); + insert(this.activeRank, i, rank); + if (trackOpen) + insert(trackOpen, i, this.cursor.from); + this.minActive = findMinIndex(this.active, this.activeTo); + } + // After calling this, if `this.point` != null, the next range is a + // point. Otherwise, it's a regular range, covered by `this.active`. + next() { + let from = this.to, wasPoint = this.point; + this.point = null; + let trackOpen = this.openStart < 0 ? [] : null, trackExtra = 0; + for (;;) { + let a = this.minActive; + if (a > -1 && (this.activeTo[a] - this.cursor.from || this.active[a].endSide - this.cursor.startSide) < 0) { + if (this.activeTo[a] > from) { + this.to = this.activeTo[a]; + this.endSide = this.active[a].endSide; + break; + } + this.removeActive(a); + if (trackOpen) + remove(trackOpen, a); + } + else if (!this.cursor.value) { + this.to = this.endSide = 1000000000 /* Far */; + break; + } + else if (this.cursor.from > from) { + this.to = this.cursor.from; + this.endSide = this.cursor.startSide; + break; + } + else { + let nextVal = this.cursor.value; + if (!nextVal.point) { // Opening a range + this.addActive(trackOpen); + this.cursor.next(); + } + else if (wasPoint && this.cursor.to == this.to && this.cursor.from < this.cursor.to) { + // Ignore any non-empty points that end precisely at the end of the prev point + this.cursor.next(); + } + else { // New point + this.point = nextVal; + this.pointFrom = this.cursor.from; + this.pointRank = this.cursor.rank; + this.to = this.cursor.to; + this.endSide = nextVal.endSide; + if (this.cursor.from < from) + trackExtra = 1; + this.cursor.next(); + this.forward(this.to, this.endSide); + break; + } + } + } + if (trackOpen) { + let openStart = 0; + while (openStart < trackOpen.length && trackOpen[openStart] < from) + openStart++; + this.openStart = openStart + trackExtra; + } + } + activeForPoint(to) { + if (!this.active.length) + return this.active; + let active = []; + for (let i = this.active.length - 1; i >= 0; i--) { + if (this.activeRank[i] < this.pointRank) + break; + if (this.activeTo[i] > to || this.activeTo[i] == to && this.active[i].endSide >= this.point.endSide) + active.push(this.active[i]); + } + return active.reverse(); + } + openEnd(to) { + let open = 0; + for (let i = this.activeTo.length - 1; i >= 0 && this.activeTo[i] > to; i--) + open++; + return open; + } + } + function compare(a, startA, b, startB, length, comparator) { + a.goto(startA); + b.goto(startB); + let endB = startB + length; + let pos = startB, dPos = startB - startA; + for (;;) { + let diff = (a.to + dPos) - b.to || a.endSide - b.endSide; + let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB); + if (a.point || b.point) { + if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && + sameValues(a.activeForPoint(a.to + dPos), b.activeForPoint(b.to)))) + comparator.comparePoint(pos, clipEnd, a.point, b.point); + } + else { + if (clipEnd > pos && !sameValues(a.active, b.active)) + comparator.compareRange(pos, clipEnd, a.active, b.active); + } + if (end > endB) + break; + pos = end; + if (diff <= 0) + a.next(); + if (diff >= 0) + b.next(); + } + } + function sameValues(a, b) { + if (a.length != b.length) + return false; + for (let i = 0; i < a.length; i++) + if (a[i] != b[i] && !a[i].eq(b[i])) + return false; + return true; + } + function remove(array, index) { + for (let i = index, e = array.length - 1; i < e; i++) + array[i] = array[i + 1]; + array.pop(); + } + function insert(array, index, value) { + for (let i = array.length - 1; i >= index; i--) + array[i + 1] = array[i]; + array[index] = value; + } + function findMinIndex(value, array) { + let found = -1, foundPos = 1000000000 /* Far */; + for (let i = 0; i < array.length; i++) + if ((array[i] - foundPos || value[i].endSide - value[found].endSide) < 0) { + found = i; + foundPos = array[i]; + } + return found; + } + + /** + Count the column position at the given offset into the string, + taking extending characters and tab size into account. + */ + function countColumn(string, tabSize, to = string.length) { + let n = 0; + for (let i = 0; i < to;) { + if (string.charCodeAt(i) == 9) { + n += tabSize - (n % tabSize); + i++; + } + else { + n++; + i = findClusterBreak(string, i); + } + } + return n; + } + /** + Find the offset that corresponds to the given column position in a + string, taking extending characters and tab size into account. By + default, the string length is returned when it is too short to + reach the column. Pass `strict` true to make it return -1 in that + situation. + */ + function findColumn(string, col, tabSize, strict) { + for (let i = 0, n = 0;;) { + if (n >= col) + return i; + if (i == string.length) + break; + n += string.charCodeAt(i) == 9 ? tabSize - (n % tabSize) : 1; + i = findClusterBreak(string, i); + } + return strict === true ? -1 : string.length; + } + + const C = "\u037c"; + const COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C); + const SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet"); + const top = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : {}; + + // :: - Style modules encapsulate a set of CSS rules defined from + // JavaScript. Their definitions are only available in a given DOM + // root after it has been _mounted_ there with `StyleModule.mount`. + // + // Style modules should be created once and stored somewhere, as + // opposed to re-creating them every time you need them. The amount of + // CSS rules generated for a given DOM root is bounded by the amount + // of style modules that were used. So to avoid leaking rules, don't + // create these dynamically, but treat them as one-time allocations. + class StyleModule { + // :: (Object + +

Using a system font

+

Here we use origin 0 (and we can omit it).

+

fFamily needs to be an available font family.

+ + + + + + + +
JSONLottie Output
+
{
+    "fFamily": "monospace",
+    "fName": "MyFont",
+    "fStyle": "Regular"
+}
+
+

+

+

+
+
+
+
+ +
+

+
CSSOutput
+ + +
{
+    font-family: monospace;
+}
+
+ + +
+
Hello
+
+

Font from CSS URL

+

Here we use origin 1.

+ + + + + + + +
JSONLottie Output
+
{
+    "fPath": "https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap",
+    "fFamily": "Poppins",
+    "fStyle": "Bold",
+    "fName": "Poppins Bold",
+    "origin": 1
+}
+
+

+

+

+
+
+
+
+ +
+

+
CSSOutput
+ + +
 @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap');
+
+ + +or + + +
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&amp;display=swap" rel="stylesheet">
+
+ + +
+
Hello
+
+

Font from URL

+

Here we use origin 3.

+ + + + + + + +
JSONLottie Output
+
{
+    "fPath": "https://fonts.gstatic.com/s/ubuntu/v15/4iCp6KVjbNBYlgoKejZftWyI.ttf",
+    "fFamily": "Ubuntu",
+    "fStyle": "Light Italic",
+    "fName": "Ubuntu Light Italic",
+    "origin": 3
+}
+
+

+

+

+
+
+
+
+ +
+

+
CSSOutput
+ + +
@font-face {
+  font-family: 'Ubuntu';
+  font-style: italic;
+  font-weight: 300;
+  font-display: swap;
+  src: url(https://fonts.gstatic.com/s/ubuntu/v15/4iCp6KVjbNBYlgoKejZftWyI.ttf) format('truetype');
+}
+
+ + +
+
Hello
+
+

Character Data

+

You can also have font data directly into the lottie, this is done by having an +array of character data objects in the chars attribute of the animation.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
dataCharacter Shape or Character Precomp +

Defines how the character is defined

+
chstring +

Character

+
fFamilystring +

Font Family

+
sizenumber +

Font Size

+
stylestring +

Font Style

+
wnumber +

Width

+
+
+

Character Shapes

+

Defines a character as shapes

+
+ + + + + + + + + + + + + + + +
AttributeTypeDescription
shapesShape List +

Shapes forming the character

+
+
+

Character Precomp

+

Defines a character as a precomp layer

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
refIdstring +

ID of the precomp as specified in the assets

+
ksTransform +

Layer transform

+
ipnumber +

Frame when the layer becomes visible

+
opnumber +

Frame when the layer becomes invisible

+
srnumber +

Time Stretch

+
stnumber +

Start Time

+
+
+

Text Layer

+

The text layer has an attribute called t containing a Text Animator Data object.

+

Text Data

+

Contains all the text data and animation

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
aarray of Text Range +

Ranges

+
dAnimated Text Document +

Document

+
mText Alignment Options +

Alignment

+
pText Follow Path +

Follow Path

+
+
+

Animated Text Document

+

This object is similar to an animated property for text.

+

The main difference is that it's always treated as animated (ie: you must use keyframes).

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
karray of Text Document Keyframe +

Array of keyframes

+
xstring +

Expression

+
sidstring +

One of the ID in the file's slots

+
+
+

Text Document Keyframe

+

This is similar to the keyframe object used by animated properties, +but it doesn't have any attribute specifying interpolation as text is always animated in discrete steps.

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
sText Document +

Start

+
tnumber +

Time

+
+
+

Text Document

+

This is where the actual text data is stored.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
fstring +

Font Family

+
fcColor +

Fill Color

+
scColor +

Stroke Color

+
swnumber +

Stroke Width

+
ofboolean +

Render stroke above the fill

+
snumber +

Font Size

+
lhnumber +

Distance between lines on multiline or wrapped text

+
szarray of number +

Size of the box containing the text

+
psarray of number +

Position of the box containing the text

+
tstring +

Text, note that newlines are encoded with \r

+
jText Justify +

Justify

+
caText Caps +

Text Caps

+
trnumber +

Text Tracking

+
lsnumber +

Baseline Shift

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0
0
0
0
0
0
0
5
80
100
+
+
+
+
+ + +
+

Text Alignment Options

+

Used to change the origin point for transformations, such as Rotation, that may be applied to the text string. The origin point for each character, word, or line can be changed.

+
+ + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
aAnimated Vector +

Group alignment

+
gText Grouping +

Anchor point grouping

+
+
+

Text Follow Path

+

Uses the path described by a layer mask to put the text on said path.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
minteger +

Index of the mask to use

+
fAnimated number +

First Margin

+
lAnimated number +

Last Margin

+
rAnimated number +

Reverse Path

+
aAnimated number +

Force Alignment

+
pAnimated number +

Perpendicular To Path

+
+
+

Text Range

+

Range of text with custom animations and style

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
nmstring +

Name

+
sText Range Selector +

Selector

+
aText Style +

Style

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
Selector
60
75
0
0
0
Transform
0
0
0
100
Style
0
0
0
0
0
+
+
+
+
+ + +
+

Text Range Selector

+

Defines the range of characters to apply a property value only to +a specific subset of the text document.

+

r Defines whether the values are defined as a percentage or indices.

+

The range is defined by s, e, and o.

+

ne and xe define what happes to text that is only partly inside the selected range.

+

b changes whether selection is done on per character basis, per word, etc. +It also changes the meaning of an index when r is set to Indices.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
t0-1 integer +

Expressible

+
xeAnimated number +

Max Ease

+
neAnimated number +

Min Ease

+
aAnimated number +

Max Amount

+
bText Based +

Based On

+
rn0-1 integer +

Randomize

+
shText Shape +

Shape

+
oAnimated number +

Offset

+
rText Range Units +

Range Units

+
smAnimated number +

Selector Smoothness

+
sAnimated number +

Start

+
eAnimated number +

End

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
60
75
0
0
0
+
+
+
+
+ + +
+

Text Style

+

Has the properties of a transform and the style options of a text document.

+

It applies such transform and style to the part of the text defined +by the text selector property

+
+

Also has the attributes from Transform.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeTypeDescription
swAnimated number +

Stroke Width

+
scAnimated Color +

Stroke Color

+
shAnimated number +

Stroke Hue

+
ssAnimated number +

Stroke Saturation

+
sbAnimated number +

Stroke Brightness

+
soAnimated number +

Stroke Opacity

+
fcAnimated Color +

Fill Color

+
fhAnimated number +

Fill Hue

+
fsAnimated number +

Fill Saturation

+
fbAnimated number +

Fill Brightness

+
foAnimated number +

Fill Opacity

+
tAnimated number +

Letter Spacing

+
blAnimated number +

Blur

+
lsAnimated number +

Line Spacing

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Transform
0
0
0
100
Style
0
0
0
0
0
+
+
+
+
+ + +
+ + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + +