[
  {
    "id": "rbfad00000tab001",
    "type": "tab",
    "label": "Rhythmic Build fader ramp",
    "disabled": false,
    "info": "Ramp a grandMA fader through every Rhythmic Build, following a custom\ncurve, and snap it back to zero just before the section ends.\n\nEVENTS vs STREAMS\nEvery keypoint node has two outputs:\n- TOP = events: one message on enter, one on exit. Use it to TRIGGER things\n  (see the 'Keypoint cue to grandMA' example).\n- BOTTOM = stream: a continuous flow of messages (about 30 per second) while\n  the section is active, carrying live timing and progress. Use it to MOVE\n  things: faders, opacity, intensity.\nThis flow uses the stream output.\n\nTHE PROGRESS NODE\nProgress turns a stream into one simple number. Three settings matter:\n- Source: which span the 0..100% runs over.\n  - keypoint: this section only\n  - group: back-to-back sections of the SAME type count as one span\n    (two Rhythmic Builds in a row = one long ramp)  <- used here\n  - family: back-to-back sections of RELATED types count as one span\n    (Build + Rhythmic Build together form the 'build' family)\n- Window: use the whole span ('full', used here), or only the first/last\n  seconds or bars of it, or a window before/after it (pre/post).\n- Curve: double-click the graph to add points, drag points to move them,\n  drag a segment to bend it. This example rises to 100% at 95% of the group,\n  then falls back to 0 - so the fader is already reset when the next section\n  starts.\n\nTHE TWO OUTPUTS\n- 'Set FaderTemp command' turns the number into a grandMA command\n  ('Fadertemp sequence 194 at 0..100') and sends it to /cmd.\n- 'Progression' sends the raw 0..1 value to /time-line/build-progress and\n  shows a live progress bar in the Automations view, so you can watch the\n  curve move.\n\nSETUP - GRANDMA\nDouble-click an OSC output node, then click the pencil icon next to 'Server'\nand set the console's IP and OSC port. Enable OSC input on the console and\nchange 'sequence 194' to the sequence you want to drive.\n\nTESTING\nNo deck playing? Click the test buttons to simulate the stream at different\npoints in the group: 25%, 75%, 95% (the peak) and 99% (already back near\nzero). Watch the debug sidebar and the progress bar.\n",
    "env": []
  },
  {
    "id": "rbfad00000grp001",
    "type": "group",
    "z": "rbfad00000tab001",
    "name": "Fader ramp - follows the Rhythmic Build group",
    "style": {
      "label": true
    },
    "nodes": [
      "rbfad00000key001",
      "rbfad00000prg001",
      "rbfad00000fnc001",
      "rbfad00000out001",
      "rbfad00000out002",
      "rbfad00000dbg001"
    ],
    "x": 54,
    "y": 39,
    "w": 952,
    "h": 262
  },
  {
    "id": "rbfad00000grp002",
    "type": "group",
    "z": "rbfad00000tab001",
    "name": "No deck playing? Test with these",
    "style": {
      "label": true
    },
    "nodes": [
      "rbfad00000inj001",
      "rbfad00000inj002",
      "rbfad00000inj003",
      "rbfad00000inj004"
    ],
    "x": 54,
    "y": 339,
    "w": 292,
    "h": 262
  },
  {
    "id": "rbfad00000key001",
    "type": "tl-keypoint-rhythmic-build",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp001",
    "x": 190,
    "y": 180,
    "wires": [
      [],
      [
        "rbfad00000prg001"
      ]
    ]
  },
  {
    "id": "rbfad00000prg001",
    "type": "tl-progress",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp001",
    "progressType": "group",
    "windowMode": "full",
    "seconds": "5",
    "bars": "2",
    "outputMin": "0",
    "outputMax": "1",
    "curvePoints": "[{\"x\":0,\"y\":0},{\"x\":0.95,\"y\":1},{\"x\":1,\"y\":0}]",
    "curveSegments": "{\"0\":{\"bend\":0.525},\"1\":{\"bend\":-0.5}}",
    "onlyWhilePlaying": false,
    "x": 430,
    "y": 180,
    "wires": [
      [
        "rbfad00000fnc001",
        "rbfad00000out002"
      ]
    ]
  },
  {
    "id": "rbfad00000fnc001",
    "type": "function",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp001",
    "name": "Set FaderTemp command",
    "func": "// Progress gives us a number between 0 and 1.\n// grandMA wants a fader level between 0 and 100.\nconst level = Math.round(msg.payload * 1000) / 10;\nmsg.payload = `Fadertemp sequence 194 at ${level}`;\nreturn msg;",
    "outputs": 1,
    "timeout": 0,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "libs": [],
    "x": 680,
    "y": 180,
    "wires": [
      [
        "rbfad00000out001",
        "rbfad00000dbg001"
      ]
    ]
  },
  {
    "id": "rbfad00000out001",
    "type": "tl-output",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp001",
    "name": "MA: FaderTemp",
    "protocol": "osc",
    "server": "rbfad00000srv001",
    "address": "/cmd",
    "message": "",
    "vizType": "led",
    "textSuffix": "",
    "progressMin": 0,
    "progressMax": 1,
    "progressStartLabel": "",
    "progressEndLabel": "",
    "x": 920,
    "y": 180,
    "wires": []
  },
  {
    "id": "rbfad00000out002",
    "type": "tl-output",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp001",
    "name": "Progression",
    "protocol": "osc",
    "server": "rbfad00000srv001",
    "address": "/time-line/build-progress",
    "message": "",
    "vizType": "progress",
    "textSuffix": "",
    "progressMin": 0,
    "progressMax": 1,
    "progressStartLabel": "",
    "progressEndLabel": "",
    "x": 670,
    "y": 260,
    "wires": []
  },
  {
    "id": "rbfad00000dbg001",
    "type": "debug",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp001",
    "name": "command sent",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "true",
    "targetType": "full",
    "statusVal": "",
    "statusType": "auto",
    "x": 920,
    "y": 100,
    "wires": []
  },
  {
    "id": "rbfad00000inj001",
    "type": "inject",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp002",
    "name": "test: 25% of group",
    "props": [
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "topic": "",
    "payload": "{\"currentKeypointGroupProgress\":0.25}",
    "payloadType": "json",
    "x": 190,
    "y": 380,
    "wires": [
      [
        "rbfad00000prg001"
      ]
    ]
  },
  {
    "id": "rbfad00000inj002",
    "type": "inject",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp002",
    "name": "test: 75% of group",
    "props": [
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "topic": "",
    "payload": "{\"currentKeypointGroupProgress\":0.75}",
    "payloadType": "json",
    "x": 190,
    "y": 440,
    "wires": [
      [
        "rbfad00000prg001"
      ]
    ]
  },
  {
    "id": "rbfad00000inj003",
    "type": "inject",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp002",
    "name": "test: 95% (peak)",
    "props": [
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "topic": "",
    "payload": "{\"currentKeypointGroupProgress\":0.95}",
    "payloadType": "json",
    "x": 190,
    "y": 500,
    "wires": [
      [
        "rbfad00000prg001"
      ]
    ]
  },
  {
    "id": "rbfad00000inj004",
    "type": "inject",
    "z": "rbfad00000tab001",
    "g": "rbfad00000grp002",
    "name": "test: 99% (reset)",
    "props": [
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": 0.1,
    "topic": "",
    "payload": "{\"currentKeypointGroupProgress\":0.99}",
    "payloadType": "json",
    "x": 190,
    "y": 560,
    "wires": [
      [
        "rbfad00000prg001"
      ]
    ]
  },
  {
    "id": "rbfad00000srv001",
    "type": "tl-output-server",
    "name": "grandMA",
    "protocol": "osc",
    "host": "127.0.0.1",
    "port": 8000,
    "udpFamily": "udp4"
  }
]
