{
    "effectName": "Morph",
    "properties": [
        {
            "id": "Morph_LineEditor",
            "label": "",
            "type": "string",
            "controlType": "custom",
            "platform": "ipad",
            "default": "",
            "description": "iPad-only touch editor showing the current Start (blue) and End (orange) lines on a 100x100 grid. Drag the four labelled endpoints to reposition; linked-point pairs (see Link Points) follow their master. Desktop skips this entry; desktop users edit via the sliders below."
        },
        {
            "id": "Morph_Start_X1",
            "label": "X1a",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "X coordinate of the first endpoint of the starting line (side A start). Defines where the morph begins on one side."
        },
        {
            "id": "Morph_Start_Y1",
            "label": "Y1a",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Y coordinate of the first endpoint of the starting line (side A start). Defines where the morph begins on one side."
        },
        {
            "id": "Morph_Start_X2",
            "label": "X1b",
            "type": "int",
            "controlType": "slider",
            "default": 100,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "X coordinate of the second endpoint of the starting line (side B start). Together with X1a/Y1a, defines the width and angle of the starting line."
        },
        {
            "id": "Morph_Start_Y2",
            "label": "Y1b",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Y coordinate of the second endpoint of the starting line (side B start). Together with X1b, defines the other end of the starting line."
        },
        {
            "id": "MorphStartLength",
            "label": "Head Length",
            "type": "int",
            "controlType": "slider",
            "default": 1,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Length of the colored head at the start of the morph. This value blends with the end head length as the morph progresses."
        },
        {
            "id": "Morph_Start_Link",
            "label": "Link Points",
            "type": "bool",
            "controlType": "checkbox",
            "default": false,
            "description": "When enabled, the second start point (X1b/Y1b) is locked to the first start point (X1a/Y1a), making the start a single point instead of a line."
        },
        {
            "id": "Morph_End_X1",
            "label": "X2a",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "X coordinate of the first endpoint of the ending line (side A end). Defines where the morph finishes on one side."
        },
        {
            "id": "Morph_End_Y1",
            "label": "Y2a",
            "type": "int",
            "controlType": "slider",
            "default": 100,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Y coordinate of the first endpoint of the ending line (side A end). Defines where the morph finishes on one side."
        },
        {
            "id": "Morph_End_X2",
            "label": "X2b",
            "type": "int",
            "controlType": "slider",
            "default": 100,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "X coordinate of the second endpoint of the ending line (side B end). Together with X2a/Y2a, defines the width and angle of the ending line."
        },
        {
            "id": "Morph_End_Y2",
            "label": "Y2b",
            "type": "int",
            "controlType": "slider",
            "default": 100,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Y coordinate of the second endpoint of the ending line (side B end). Together with X2b, defines the other end of the ending line."
        },
        {
            "id": "MorphEndLength",
            "label": "Head Length",
            "type": "int",
            "controlType": "slider",
            "default": 1,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Length of the colored head at the end of the morph. The head length transitions from the start value to this value as the morph progresses."
        },
        {
            "id": "Morph_End_Link",
            "label": "Link Points",
            "type": "bool",
            "controlType": "checkbox",
            "default": false,
            "description": "When enabled, the second end point (X2b/Y2b) is locked to the first end point (X2a/Y2a), making the end a single point instead of a line."
        },
        {
            "id": "MorphDuration",
            "label": "Head Duration",
            "type": "int",
            "controlType": "slider",
            "default": 20,
            "min": 0,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Percentage of the effect duration during which the head is visible and moving. The remaining time shows only the fading tail."
        },
        {
            "id": "MorphAccel",
            "label": "Acceleration",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": -10,
            "max": 10,
            "valueCurve": true,
            "lockable": true,
            "description": "Applies acceleration or deceleration to the morph movement. Positive values speed up toward the end, negative values slow down."
        },
        {
            "id": "Morph_Repeat_Count",
            "label": "Repeat Count",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": 0,
            "max": 250,
            "valueCurve": true,
            "lockable": true,
            "description": "Number of parallel copies of the morph drawn alongside the original. Creates multiple evenly-spaced morph lines across the model."
        },
        {
            "id": "Morph_Repeat_Skip",
            "label": "Repeat Skip",
            "type": "int",
            "controlType": "slider",
            "default": 1,
            "min": 1,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Pixel spacing between each repeated morph copy. Higher values spread the repeated morphs farther apart."
        },
        {
            "id": "Morph_Stagger",
            "label": "Stagger",
            "type": "int",
            "controlType": "slider",
            "default": 0,
            "min": -100,
            "max": 100,
            "valueCurve": true,
            "lockable": true,
            "description": "Time offset between repeated morph copies so they start at different times, creating a wave or cascade effect. Negative values reverse the stagger order."
        },
        {
            "id": "ShowHeadAtStart",
            "label": "Show Head at Start",
            "type": "bool",
            "controlType": "checkbox",
            "default": false,
            "lockable": true,
            "description": "When enabled, the full head is visible at the starting position from the first frame, rather than growing in from nothing."
        },
        {
            "id": "Morph_AutoRepeat",
            "label": "Auto Repeat",
            "type": "bool",
            "controlType": "checkbox",
            "default": false,
            "lockable": true,
            "description": "Automatically calculates the repeat count needed to fill the entire model based on the morph size and skip spacing."
        },
        {
            "id": "Morph_QuickSet",
            "label": "Quick Set",
            "type": "string",
            "controlType": "custom",
            "default": "",
            "description": "Preset start/end point configurations (Full or Single Sweep in each direction) that write predefined values into all eight X/Y coordinate fields at once. Selection resets to blank after the preset is applied."
        },
        {
            "id": "Morph_Swap",
            "label": "",
            "type": "string",
            "controlType": "custom",
            "default": "",
            "description": "Swap the start and end X/Y coordinate values (and any active value curves) so the morph plays in reverse."
        }
    ],
    "groups": [
        {
            "type": "tabs",
            "tabs": [
                {
                    "label": "Start",
                    "properties": [
                        "Morph_Start_X1",
                        "Morph_Start_Y1",
                        "Morph_Start_X2",
                        "Morph_Start_Y2",
                        "MorphStartLength",
                        "Morph_Start_Link",
                        "Morph_QuickSet"
                    ]
                },
                {
                    "label": "End",
                    "properties": [
                        "Morph_End_X1",
                        "Morph_End_Y1",
                        "Morph_End_X2",
                        "Morph_End_Y2",
                        "MorphEndLength",
                        "Morph_End_Link"
                    ]
                },
                {
                    "label": "Options",
                    "properties": [
                        "MorphDuration",
                        "MorphAccel",
                        "Morph_Repeat_Count",
                        "Morph_Repeat_Skip",
                        "Morph_Stagger",
                        "ShowHeadAtStart",
                        "Morph_AutoRepeat",
                        "Morph_Swap"
                    ]
                }
            ],
            "settingKey": "E_NOTEBOOK_Morph"
        }
    ],
    "visibilityRules": [
        {
            "when": { "property": "Morph_Start_Link", "equals": true },
            "disable": ["Morph_Start_X2", "Morph_Start_Y2"]
        },
        {
            "when": { "property": "Morph_End_Link", "equals": true },
            "disable": ["Morph_End_X2", "Morph_End_Y2"]
        }
    ]
}
