{
  "version": "1.24.0",
  "createdWith": "Open Stage Control",
  "type": "fragment",
  "content": {
    "type": "panel",
    "top": 90,
    "left": 160,
    "lock": false,
    "id": "@{parent.id}_env",
    "visible": true,
    "interaction": true,
    "comments": "",
    "width": 440,
    "height": 310,
    "expand": "false",
    "colorText": "auto",
    "colorWidget": "auto",
    "colorStroke": "auto",
    "colorFill": "auto",
    "alphaStroke": "auto",
    "alphaFillOff": "auto",
    "alphaFillOn": "auto",
    "lineWidth": "auto",
    "borderRadius": "auto",
    "padding": "auto",
    "html": "",
    "css": "",
    "colorBg": "auto",
    "layout": "default",
    "justify": "start",
    "gridTemplate": "",
    "contain": true,
    "scroll": true,
    "innerPadding": true,
    "variables": "@{parent.variables}",
    "traversing": false,
    "value": "",
    "default": "",
    "linkId": "",
    "address": "auto",
    "preArgs": "",
    "typeTags": "",
    "decimals": 2,
    "target": "",
    "ignoreDefaults": false,
    "bypass": false,
    "onCreate": "",
    "onValue": "",
    "widgets": [
      {
        "type": "variable",
        "lock": false,
        "id": "@{parent.id}_vals",
        "comments": "",
        "value": "",
        "default": [
          [
            0,
            0.5
          ],
          [
            0.5,
            0.5
          ],
          [
            1,
            0.5
          ]
        ],
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "typeTags": "",
        "decimals": 2,
        "target": "",
        "ignoreDefaults": false,
        "bypass": false,
        "onCreate": "",
        "onValue": ""
      },
      {
        "type": "canvas",
        "top": 30,
        "left": 0,
        "lock": false,
        "id": "@{parent.id}_canvas",
        "visible": true,
        "interaction": true,
        "comments": "",
        "width": "auto",
        "height": "auto",
        "expand": "false",
        "colorText": "auto",
        "colorWidget": "auto",
        "colorStroke": "auto",
        "colorFill": "auto",
        "alphaStroke": "auto",
        "alphaFillOff": "auto",
        "alphaFillOn": "auto",
        "lineWidth": "auto",
        "borderRadius": "auto",
        "padding": "auto",
        "html": "",
        "css": ":host {\n\n    width: 100%;\n    height: calc(100% - 70rem);\n\n}",
        "valueLength": 64,
        "autoClear": true,
        "continuous": false,
        "value": "",
        "default": "",
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "typeTags": "",
        "decimals": 2,
        "target": "",
        "ignoreDefaults": false,
        "bypass": false,
        "onCreate": "set(getProp(\"parent\", \"id\") + \"_size\", 3)\nvalue[0] = [0.0, 0.5]\nvalue[1] = [0.5, 0.5]\nvalue[2] = [1.0, 0.5]\n\nlocals.eucDistance = function(p1, p2) {\n  var a = p1[0] - p2[0];\n  var b = p1[1] - (1 - p2[1]);\n  return Math.sqrt( a*a + b*b );\n}\n\nlocals.closest = function(v, x, y, s){\n  return (v.slice(0, s).reduce((a, b) => \n  locals.eucDistance([x, y], a) < locals.eucDistance([x, y], b) ? a : b));\n}\n\nlocals.cIndex = 1\nlocals.cDist = 0\n\nsetVar(this, 'reset', function() {\n  set(getProp(\"parent\", \"id\") + \"_size\", 3)\n  var val = []\n  val.length = 64; \n  val.fill(0);\n  val[0] = [0.0, 0.5]\n  val[1] = [0.5, 0.5]\n  val[2] = [1.0, 0.5]\n  set(getProp(\"parent\", \"id\") + '_canvas', val)\n})\n\n\nsetVar(this, 'update', function() {\n  var limits = get(getProp(\"parent\", \"id\") + '_rslider')\n  var vals = get(getProp(\"parent\", \"id\") + '_canvas')\n  var size = get(getProp(\"parent\", \"id\") + '_size')\n  set(getProp(\"parent\", \"id\") + \"_vals\", (limits).concat(vals.slice(0, size).flat()));\n  var parentVariables = getProp('parent', 'variables')\n  if (parentVariables.grandparent) {\n    set(parentVariables.grandparent + '_vals', value)\n  }\n})\n",
        "onValue": "// apply limits\nfor(var i = 0; i < get(getProp(\"parent\", \"id\") + \"_size\"); i += 1) {\n  if(typeof value[i] === 'string') {value[i] = JSON.parse(value[i])}\n  value[i] = [Math.max(0, Math.min(1, value[i][0])), Math.max(0, Math.min(1, value[i][1]))]\n}\n\n// re-update widget value without retriggering script or sending message\nset(\"this\", value, {sync: true, send: false})\ngetVar('this', 'update')()",
        "onTouch": "var lock = false\n\n// store normalized coordinates\nif (event.type == \"start\") {\n    locals.x = event.offsetX / width\n    locals.y = event.offsetY / height\n    lock = true\n    locals.cIndex = value.indexOf(locals.closest(value, locals.x, locals.y, get(getProp(\"parent\", \"id\") + \"_size\")))\n    locals.cDist = locals.eucDistance([locals.x, locals.y], value[locals.cIndex])\n} else {\n    // when the pointer is moving, increment coordinates\n    // because offsetX and offsetY may not be relevant\n    // if the pointer hovers a different widgets\n    locals.x += event.movementX / width\n    locals.y += event.movementY / height\n}\n\n\nif(lock && (locals.cDist > 0.1) && (locals.x >= 0) && (locals.y >= 0) && (locals.x <= 1) && (locals.y <= 1)) {\n  value[get(getProp(\"parent\", \"id\") + \"_size\")] = [locals.x, 1 - locals.y]\n  value.sort((a, b) => a[0] - b[0])\n  locals.cIndex = value.indexOf(locals.closest(value, locals.x, locals.y, get(getProp(\"parent\", \"id\") + \"_size\")))\n  set(getProp(\"parent\", \"id\") + '_size', get(getProp(\"parent\", \"id\") + \"_size\") + 1)\n} else {\n  value[locals.cIndex] = [locals.x, 1 - locals.y]\n}\n\nvar min = get(getProp(\"parent\", \"id\") + \"_input_min\")\nvar max = get(getProp(\"parent\", \"id\") + \"_input_max\")\n\nif (event.type != \"stop\") {\n  set(getProp(\"parent\", \"id\") + \"_mpos\", \"x: \" + ((locals.x * (max - min)) + min).toFixed(2) + \"\\ny: \" + (1 - locals.y).toFixed(2))\n} else {\n  lock = false\n  set(getProp(\"parent\", \"id\") + \"_mpos\", \"\")\n}\nset(\"this\", value)",
        "onDraw": "//var size = get('@{parent.id}_size')\nfor(var i = 0; i < get(getProp(\"parent\", \"id\") + \"_size\"); i += 1) {\n  ctx.fillStyle = cssVars.colorFill\n  ctx.fillRect(value[i][0] * width - 2.5, (1 - value[i][1]) * height - 2.5, 5, 5)\n}\n\nctx.stroke();\nctx.strokeStyle = cssVars.colorFill\nctx.beginPath();\n\nfor(var i = 0; i < get(getProp(\"parent\", \"id\") + \"_size\"); i += 1) {\n  if(i === 0){\n    ctx.moveTo(value[i][0] * width, (1 - value[i][1]) * height)\n  } else {\n    ctx.lineTo(value[i][0] * width, (1 - value[i][1]) * height); // Draw a line to (150, 100)\n  }\n}\n\nctx.stroke();",
        "onResize": ""
      },
      {
        "type": "variable",
        "lock": false,
        "id": "@{parent.id}_size",
        "comments": "",
        "value": "",
        "default": 3,
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "typeTags": "",
        "decimals": 2,
        "target": "",
        "ignoreDefaults": false,
        "bypass": false,
        "onCreate": "",
        "onValue": ""
      },
      {
        "type": "button",
        "top": "auto",
        "left": 0,
        "lock": false,
        "id": "@{parent.id}_flatten",
        "visible": true,
        "interaction": true,
        "comments": "",
        "width": 30,
        "height": 30,
        "expand": "false",
        "colorText": "auto",
        "colorWidget": "auto",
        "colorStroke": "auto",
        "colorFill": "auto",
        "alphaStroke": "auto",
        "alphaFillOff": "auto",
        "alphaFillOn": "auto",
        "lineWidth": "auto",
        "borderRadius": "auto",
        "padding": "auto",
        "html": "",
        "css": ":host {\n\n    top: calc(100% - 30rem);\n\n}",
        "colorTextOn": "auto",
        "label": "F",
        "vertical": false,
        "wrap": false,
        "on": 1,
        "off": 0,
        "mode": "push",
        "doubleTap": false,
        "decoupled": false,
        "value": "",
        "default": "",
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "typeTags": "",
        "decimals": 2,
        "target": "",
        "ignoreDefaults": false,
        "bypass": false,
        "onCreate": "",
        "onValue": "if(value === 1){\n  getVar(getProp(\"parent\", \"id\") + '_canvas', 'reset')()\n}"
      },
      {
        "type": "range",
        "top": 0,
        "left": 50,
        "lock": false,
        "id": "@{parent.id}_rslider",
        "visible": true,
        "interaction": true,
        "comments": "",
        "width": "auto",
        "height": 30,
        "expand": "false",
        "colorText": "auto",
        "colorWidget": "auto",
        "colorStroke": "auto",
        "colorFill": "auto",
        "alphaStroke": "auto",
        "alphaFillOff": "auto",
        "alphaFillOn": "auto",
        "lineWidth": "auto",
        "borderRadius": "auto",
        "padding": "auto",
        "html": "",
        "css": ":host {\n\n    width: calc(100% - 100rem);\n\n}",
        "design": "default",
        "knobSize": "auto",
        "horizontal": true,
        "pips": false,
        "dashed": false,
        "gradient": [],
        "snap": true,
        "spring": false,
        "doubleTap": false,
        "range": "{\n  \"min\": @{parent.variables.min},\n  \"max\": @{parent.variables.max}\n}",
        "logScale": false,
        "sensitivity": 1,
        "steps": "",
        "value": "[@{@{parent.id}_input_min.value}, @{@{parent.id}_input_max.value}]",
        "default": "[\n  @{parent.variables.min},\n  @{parent.variables.max}\n]",
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "typeTags": "",
        "decimals": 2,
        "target": "",
        "ignoreDefaults": false,
        "bypass": false,
        "onCreate": "",
        "onValue": "getVar(getProp(\"parent\", \"id\") + '_canvas', 'update')()",
        "onTouch": ""
      },
      {
        "type": "input",
        "top": 0,
        "left": "auto",
        "lock": false,
        "id": "@{parent.id}_input_max",
        "visible": true,
        "interaction": true,
        "comments": "",
        "width": 50,
        "height": "auto",
        "expand": "false",
        "colorText": "auto",
        "colorWidget": "auto",
        "colorStroke": "auto",
        "colorFill": "auto",
        "alphaStroke": "auto",
        "alphaFillOff": "auto",
        "alphaFillOn": "auto",
        "lineWidth": "auto",
        "borderRadius": "auto",
        "padding": "auto",
        "html": "",
        "css": ":host {\n\n    left: calc(100% - 50rem);\n\n}",
        "align": "center",
        "unit": "",
        "asYouType": false,
        "numeric": false,
        "validation": "",
        "maxLength": "",
        "value": "@{@{parent.id}_rslider.value.1}",
        "default": "",
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "typeTags": "",
        "decimals": "@{parent.variables.decimals}",
        "target": "",
        "ignoreDefaults": false,
        "bypass": true,
        "onCreate": "",
        "onValue": ""
      },
      {
        "type": "input",
        "top": 0,
        "left": 0,
        "lock": false,
        "id": "@{parent.id}_input_min",
        "visible": true,
        "comments": "",
        "width": 50,
        "height": "auto",
        "expand": "false",
        "colorText": "auto",
        "colorWidget": "auto",
        "colorStroke": "auto",
        "colorFill": "auto",
        "alphaStroke": "auto",
        "alphaFillOff": "auto",
        "alphaFillOn": "auto",
        "lineWidth": "auto",
        "borderRadius": "auto",
        "padding": "auto",
        "html": "",
        "css": "",
        "align": "center",
        "value": "@{@{parent.id}_rslider.value.0}",
        "default": "",
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "decimals": "@{parent.variables.decimals}",
        "target": "",
        "onCreate": "",
        "onValue": "",
        "interaction": true,
        "unit": "",
        "asYouType": false,
        "numeric": false,
        "validation": "",
        "maxLength": "",
        "typeTags": "",
        "ignoreDefaults": false,
        "bypass": true
      },
      {
        "type": "text",
        "top": "auto",
        "left": "auto",
        "lock": false,
        "id": "@{parent.id}_mpos",
        "visible": true,
        "comments": "",
        "width": 130,
        "height": 40,
        "expand": "false",
        "colorText": "auto",
        "colorWidget": "auto",
        "colorStroke": "auto",
        "colorFill": "auto",
        "alphaStroke": "auto",
        "alphaFillOff": "auto",
        "alphaFillOn": "auto",
        "lineWidth": "auto",
        "borderRadius": "auto",
        "padding": "auto",
        "html": "",
        "css": ":host {\n\n    top: calc(100% - 40rem);\n    left: calc(50% - 65rem);\n\n}",
        "align": "center",
        "value": "",
        "default": "",
        "linkId": "",
        "address": "auto",
        "preArgs": "",
        "decimals": 2,
        "target": "",
        "onCreate": "",
        "onValue": "",
        "vertical": false,
        "wrap": false
      }
    ],
    "tabs": [],
    "tabsPosition": "top"
  }
}