Timothy Pomeroy 2 年 前
コミット
59acdcf678

+ 2 - 2
.env

@@ -1,4 +1,4 @@
 CLIENTS='["10.10.10.100","10.10.10.101","10.10.10.102","10.10.10.103"]'
 NAMES='["Stage","Yellow Tower","Blue Tower","Red Tower"]'
-# CLIENTS='["192.168.1.121"]'
-# NAMES='["POC"]'
+# CLIENTS='["192.168.1.122","192.168.1.113"]'
+# NAMES='["POC1","POC2"]'

+ 171 - 0
app/instances/page.js

@@ -0,0 +1,171 @@
+"use client";
+
+import { debounce } from "lodash";
+import { useEffect, useState } from "react";
+import { Collapse, Loader } from "tiny-ui";
+import { WLEDClient } from "wled-client";
+
+import { Layout, Management } from "components";
+
+const CLIENTS = process.env.CLIENTS || [];
+const NAMES = process.env.NAMES || [];
+
+export default function Home() {
+  const [names, setNames] = useState(null);
+  const [clients, setClients] = useState(null);
+  const [connections, setConnections] = useState(null);
+
+  useEffect(() => {
+    let t = [];
+    let c = [];
+    let n = [];
+    for (let client of CLIENTS) {
+      c.push(client);
+      t.push(new WLEDClient(client));
+    }
+    for (let name of NAMES) {
+      n.push(name);
+    }
+    setClients(c);
+    setConnections(t);
+    setNames(n);
+  }, []);
+
+  const handleCopy = async (payload) => {
+    if (payload?.clients && payload?.value) {
+      for (let client of payload.clients) {
+        let indx = clients.findIndex((o) => o === client);
+        if (connections[indx]) {
+          let wled = connections[indx];
+          for (let n of Object.keys(payload?.value)) {
+            if (n && payload?.value?.[n]) {
+              console.log("handleCopy", n, payload?.value[n]);
+              await wled.savePreset(n, payload?.value[n]);
+            }
+          }
+          await wled.reinit();
+        }
+      }
+    }
+  };
+
+  const handleDelete = async (payload) => {
+    if (payload?.clients && payload?.value) {
+      for (let client of payload?.clients) {
+        let indx = clients.findIndex((o) => o === client);
+        if (connections[indx]) {
+          let wled = connections[indx];
+          for (let n of payload?.value) {
+            await wled.deletePreset(n);
+          }
+          await wled.reinit();
+        }
+      }
+    }
+  };
+
+  const handleSync = async (payload) => {
+    if (payload?.clients) {
+      for (let client of payload?.clients) {
+        let indx = clients.findIndex((o) => o === client);
+        if (connections[indx]) {
+          let wled = connections[indx];
+          switch (payload?.value) {
+            case "enable":
+              await wled.enableUDPSync({ send: true, receive: false });
+              break;
+            case "disable":
+              await wled.disableUDPSync();
+              break;
+          }
+          await wled.reinit();
+        }
+      }
+    }
+  };
+
+  const handlePower = async (payload) => {
+    if (payload?.clients && payload?.value) {
+      for (let client of payload?.clients) {
+        let indx = clients.findIndex((o) => o === client);
+        if (connections[indx]) {
+          let wled = connections[indx];
+          switch (payload?.value) {
+            case "on":
+              await wled.turnOn();
+              await wled.reinit();
+              break;
+            case "off":
+              await wled.turnOff();
+              await wled.reinit();
+              break;
+            case "toggle":
+              await wled.toggle();
+              await wled.reinit();
+              break;
+            case "reboot":
+              await wled.reboot();
+              setTimeout(async () => {
+                await wled.reinit(true);
+              }, 3000);
+              break;
+          }
+        }
+      }
+    }
+  };
+
+  const handleBrightness = async (payload) => {
+    if (payload?.clients && payload?.value) {
+      for (let client of payload?.clients) {
+        let indx = clients.findIndex((o) => o === client);
+        if (connections[indx]) {
+          let wled = connections[indx];
+          await wled.setBrightness(payload?.value);
+          await wled.reinit();
+        }
+      }
+    }
+  };
+  const debounceHandleBrightness = debounce(handleBrightness, 500);
+
+  const handlePreset = async (payload) => {
+    if (payload?.clients && payload?.value) {
+      for (let client of payload?.clients) {
+        let indx = clients.findIndex((o) => o === client);
+        if (connections[indx]) {
+          let wled = connections[indx];
+          await wled.setPreset(payload?.value);
+          await wled.reinit();
+        }
+      }
+    }
+  };
+
+  return (
+    <Layout page="home">
+      {(connections && clients && (
+        <Collapse bordered={false}>
+          {clients?.map((o, i) => (
+            <Management
+              key={i + 1}
+              itemKey={`${i + 1}`}
+              clients={clients}
+              client={o}
+              clientName={names[i]}
+              connection={connections[i]}
+              onCopy={handleCopy}
+              onDelete={handleDelete}
+              onSync={handleSync}
+              onPower={handlePower}
+              onBrightness={debounceHandleBrightness}
+              onPreset={handlePreset}
+            />
+          ))}
+        </Collapse>
+      )) || <Loader size="lg" />}
+    </Layout>
+  );
+
+  return;
+}

+ 16 - 117
app/page.js

@@ -1,11 +1,13 @@
 "use client";
 
-import { debounce } from "lodash";
 import { useEffect, useState } from "react";
-import { Collapse, Loader } from "tiny-ui";
+import { Col, Loader, Row } from "tiny-ui";
 import { WLEDClient } from "wled-client";
 
-import { Layout, Management } from "./components";
+import { Automation, Layout } from "components";
+
+import automation from "data/automation.json";
+import presets from "data/presets.json";
 
 const CLIENTS = process.env.CLIENTS || [];
 const NAMES = process.env.NAMES || [];
@@ -31,103 +33,6 @@ export default function Home() {
     setNames(n);
   }, []);
 
-  const handleCopy = async (payload) => {
-    if (payload?.clients && payload?.value) {
-      for (let client of payload.clients) {
-        let indx = clients.findIndex((o) => o === client);
-        if (connections[indx]) {
-          let wled = connections[indx];
-          for (let n of Object.keys(payload?.value)) {
-            if (n && payload?.value?.[n]) {
-              await wled.savePreset(n, payload?.value[n]);
-            }
-          }
-          await wled.reinit();
-        }
-      }
-    }
-  };
-
-  const handleDelete = async (payload) => {
-    if (payload?.clients && payload?.value) {
-      for (let client of payload?.clients) {
-        let indx = clients.findIndex((o) => o === client);
-        if (connections[indx]) {
-          let wled = connections[indx];
-          for (let n of payload?.value) {
-            await wled.deletePreset(n);
-          }
-          await wled.reinit();
-        }
-      }
-    }
-  };
-
-  const handleSync = async (payload) => {
-    if (payload?.clients) {
-      for (let client of payload?.clients) {
-        let indx = clients.findIndex((o) => o === client);
-        if (connections[indx]) {
-          let wled = connections[indx];
-          switch (payload?.value) {
-            case "enable":
-              await wled.enableUDPSync({ send: true, receive: false });
-              break;
-            case "disable":
-              await wled.disableUDPSync();
-              break;
-          }
-          await wled.reinit();
-        }
-      }
-    }
-  };
-
-  const handlePower = async (payload) => {
-    if (payload?.clients && payload?.value) {
-      for (let client of payload?.clients) {
-        let indx = clients.findIndex((o) => o === client);
-        if (connections[indx]) {
-          let wled = connections[indx];
-          switch (payload?.value) {
-            case "on":
-              await wled.turnOn();
-              await wled.reinit();
-              break;
-            case "off":
-              await wled.turnOff();
-              await wled.reinit();
-              break;
-            case "toggle":
-              await wled.toggle();
-              await wled.reinit();
-              break;
-            case "reboot":
-              await wled.reboot();
-              setTimeout(async () => {
-                await wled.reinit(true);
-              }, 3000);
-              break;
-          }
-        }
-      }
-    }
-  };
-
-  const handleBrightness = async (payload) => {
-    if (payload?.clients && payload?.value) {
-      for (let client of payload?.clients) {
-        let indx = clients.findIndex((o) => o === client);
-        if (connections[indx]) {
-          let wled = connections[indx];
-          await wled.setBrightness(payload?.value);
-          await wled.reinit();
-        }
-      }
-    }
-  };
-  const debounceHandleBrightness = debounce(handleBrightness, 500);
-
   const handlePreset = async (payload) => {
     if (payload?.clients && payload?.value) {
       for (let client of payload?.clients) {
@@ -143,26 +48,20 @@ export default function Home() {
 
   return (
     <Layout page="home">
-      {(connections && clients && (
-        <Collapse bordered={false}>
-          {clients?.map((o, i) => (
-            <Management
-              key={i + 1}
-              itemKey={`${i + 1}`}
+      <Row style={{ backgroundColor: "#fff" }}>
+        <Col style={{ margin: "2rem" }}>
+          {(connections && clients && (
+            <Automation
               clients={clients}
-              client={o}
-              clientName={names[i]}
-              connection={connections[i]}
-              onCopy={handleCopy}
-              onDelete={handleDelete}
-              onSync={handleSync}
-              onPower={handlePower}
-              onBrightness={debounceHandleBrightness}
+              connections={connections}
+              names={names}
+              presets={presets}
+              automation={automation}
               onPreset={handlePreset}
             />
-          ))}
-        </Collapse>
-      )) || <Loader size="lg" />}
+          )) || <Loader size="lg" />}
+        </Col>
+      </Row>
     </Layout>
   );
 

+ 82 - 0
components/Automation.js

@@ -0,0 +1,82 @@
+import { useEffect, useState } from "react";
+import { Button, Col, Icon, Row, Steps } from "tiny-ui";
+
+const { Step } = Steps;
+
+const Automation = ({
+  automation,
+  presets,
+  clients,
+  names,
+  onPreset,
+  ...props
+}) => {
+  const [current, setCurrent] = useState(-1);
+  const [total, setTotal] = useState();
+
+  useEffect(() => {
+    setTotal((automation && Object.keys(automation)) || 0);
+  }, [automation]);
+
+  useEffect(() => {
+    if (current > -1) {
+      let indx = current + 1;
+      let payload = {
+        clients: automation?.[indx] || [],
+        value: indx
+      };
+      onPreset(payload);
+    }
+  }, [current]);
+
+  const getTitle = (indx) => presets?.[indx]?.name || indx;
+  const getName = (v) => {
+    let indx = clients?.findIndex((o) => o === v);
+    return indx > -1 ? names?.[indx] : v;
+  };
+  const getDescription = (indx) => {
+    return automation?.[indx]?.map((o) => getName(o))?.join(", ");
+  };
+
+  let steps = Object.keys(automation).map((o, i) => {
+    return <Step key={i} title={getTitle(o)} description={getDescription(o)} />;
+  });
+
+  return (
+    <Row>
+      <Col span="12">
+        <Steps
+          current={current}
+          direction="vertical"
+          onChange={(v) => setCurrent(v)}
+        >
+          {steps}
+        </Steps>
+      </Col>
+      <Col span="12">
+        <Button.Group size="lg" round>
+          <Button
+            title="Previous"
+            icon={<Icon name="arrow-left" />}
+            onClick={() => {
+              let next = current - 1;
+              if (next < 0) next = 0;
+              setCurrent(next);
+            }}
+          />
+          <Button
+            title="Next"
+            icon={<Icon name="arrow-right" />}
+            onClick={() => {
+              let next = current + 1;
+              if (next > total) next = 0;
+              setCurrent(next);
+            }}
+          />
+        </Button.Group>
+      </Col>
+    </Row>
+  );
+};
+
+export default Automation;

+ 0 - 0
app/components/Layout.js → components/Layout.js


+ 6 - 2
app/components/Management.js → components/Management.js

@@ -77,6 +77,10 @@ const UploadModal = ({ data, client, onConfirm, ...rest }) => {
     fileReader.readAsText(e?.target?.files?.[0], "UTF-8");
     fileReader.onload = (e) => {
       if (e?.target?.result) {
+        console.log("payload", {
+          ...payload,
+          value: JSON.parse(e?.target?.result),
+        });
         setPayload({ ...payload, value: JSON.parse(e?.target?.result) });
       }
     };
@@ -339,7 +343,7 @@ const StateMangement = ({
                 onClick={(e) => {
                   e.preventDefault();
                   e.stopPropagation();
-                  setUpload({ clients: [props?.client] });
+                  setUpload({ clients: [client] });
                 }}
               >
                 <Icon name="upload" />
@@ -361,7 +365,7 @@ const StateMangement = ({
                   e.preventDefault();
                   e.stopPropagation();
                   setPurge({
-                    clients: [props?.client],
+                    clients: [client],
                     value: Object.keys(props?.presets),
                   });
                 }}

+ 5 - 1
app/components/Menu.js → components/Menu.js

@@ -2,7 +2,11 @@ import Link from "next/link";
 
 import { Menu as _Menu } from "tiny-ui";
 
-const MENU = [{ url: "/", text: "Hawkband WLED" }];
+const MENU = [
+  { url: "/", text: "Hawkband WLED" },
+  { url: "/", text: "Automation" },
+  { url: "/instances", text: "Instances" },
+];
 
 const Menu = ({ page, ...rest }) => {
   const items = MENU?.map((o, i) => (

+ 0 - 0
app/components/WLED.js → components/WLED.js


+ 1 - 0
app/components/index.js → components/index.js

@@ -1,3 +1,4 @@
+export { default as Automation } from "./Automation";
 export { default as Layout } from "./Layout";
 export { default as Management } from "./Management";
 export { default as Menu } from "./Menu";

+ 18 - 0
data/automation copy.json

@@ -0,0 +1,18 @@
+{
+  "1": ["10.10.10.100"],
+  "2": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "3": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "4": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "5": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "6": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "7": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "8": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "9": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "10": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "11": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "12": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "13": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "14": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "15": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "16": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"]
+}

+ 18 - 0
data/automation.json

@@ -0,0 +1,18 @@
+{
+  "1": ["10.10.10.100"],
+  "2": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "3": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "4": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "5": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "6": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "7": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "8": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "9": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "10": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "11": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "12": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "13": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "14": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "15": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"],
+  "16": ["10.10.10.100", "10.10.10.101", "10.10.10.102", "10.10.10.103"]
+}

+ 2042 - 0
data/presets.json

@@ -0,0 +1,2042 @@
+{
+  "1": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 30, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 57,
+        "effectSpeed": 145,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "1 part 1 opening "
+  },
+  "2": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 57,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "2 part 1 3/4"
+  },
+  "3": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 57,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "3 part 1 set 19"
+  },
+  "4": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 0,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "4 part 1 end"
+  },
+  "5": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 87,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "5 part 2 opening "
+  },
+  "6": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [255, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 87,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "6 part 2 ww feature"
+  },
+  "7": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [183, 38, 255],
+          [0, 0, 0]
+        ],
+        "effectId": 87,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 3,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "7 part 2 set 41"
+  },
+  "8": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 57,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "7A part 2 going to circles"
+  },
+  "9": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 30, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 18,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "8 part 2 set 50 circles"
+  },
+  "10": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 255],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 96,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "9 part 2 riffle toss"
+  },
+  "11": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [255, 0, 0],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 88,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "10 part 2 letter F"
+  },
+  "12": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [0, 0, 0],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 87,
+        "effectSpeed": 83,
+        "effectIntensity": 91,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "11 part 2 ending "
+  },
+  "13": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [8, 255, 0],
+          [255, 200, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 74,
+        "effectSpeed": 22,
+        "effectIntensity": 46,
+        "paletteId": 3,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "12 part 3 opening "
+  },
+  "14": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [8, 255, 0],
+          [255, 200, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 7,
+        "effectSpeed": 255,
+        "effectIntensity": 255,
+        "paletteId": 3,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "13 part 3 bolt hit"
+  },
+  "15": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [8, 255, 0],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 2,
+        "effectSpeed": 0,
+        "effectIntensity": 0,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "14 part 3 ending "
+  },
+  "16": {
+    "on": true,
+    "brightness": 255,
+    "transition": 7,
+    "mainSegment": 0,
+    "segments": [
+      {
+        "id": 0,
+        "start": 0,
+        "stop": 46,
+        "grouping": 1,
+        "spacing": 0,
+        "of": 0,
+        "on": true,
+        "freeze": false,
+        "brightness": 255,
+        "cct": 127,
+        "name": "1 Powerline",
+        "colors": [
+          [8, 255, 0],
+          [0, 0, 0],
+          [0, 0, 0]
+        ],
+        "effectId": 2,
+        "effectSpeed": 0,
+        "effectIntensity": 0,
+        "paletteId": 2,
+        "selected": true,
+        "reverse": false,
+        "mirror": false
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      },
+      {
+        "stop": 0
+      }
+    ],
+    "name": "15 end of part 3"
+  },
+  "249": {
+    "win": "win&P1=1&P2=16PL=~-",
+    "name": "999_Previous"
+  },
+  "250": {
+    "win": "win&P1=1&P2=16PL=~",
+    "name": "999_Next"
+  }
+}