Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@saulshanabrook
Created April 23, 2015 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saulshanabrook/ea466772fac00942dc78 to your computer and use it in GitHub Desktop.
Save saulshanabrook/ea466772fac00942dc78 to your computer and use it in GitHub Desktop.
<html><head><title>Lighting Design Doc</title><meta content="text/html; charset=UTF-8" http-equiv="content-type"><style type="text/css">@import url('https://themes.googleusercontent.com/fonts/css?kit=Zhfjj_gat3waL4JSju74E5KZlXp2NjsiipqDtBkg26Ji-i3ynI8NvFXysMjBstzg');.lst-kix_y291l4i7csd8-0>li{counter-increment:lst-ctn-kix_y291l4i7csd8-0}.lst-kix_m61bwifzx2vm-4>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-4}.lst-kix_y291l4i7csd8-6>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-6,decimal) ". "}.lst-kix_mrkaejkow017-7>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-7,lower-latin) ". "}.lst-kix_z1o4bed65pky-4>li{counter-increment:lst-ctn-kix_z1o4bed65pky-4}.lst-kix_mrkaejkow017-8>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-8,lower-roman) ". "}.lst-kix_m61bwifzx2vm-2>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-2}ol.lst-kix_mrkaejkow017-0.start{counter-reset:lst-ctn-kix_mrkaejkow017-0 0}.lst-kix_m61bwifzx2vm-4>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-4,lower-latin) ". "}.lst-kix_z1o4bed65pky-2>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-2,lower-roman) ". "}ol.lst-kix_y291l4i7csd8-0.start{counter-reset:lst-ctn-kix_y291l4i7csd8-0 0}ol.lst-kix_m61bwifzx2vm-8.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-8 0}.lst-kix_do2cujxbrlc6-4>li:before{content:"\0025cb "}.lst-kix_stesj8k94dvq-5>li:before{content:"\0025a0 "}.lst-kix_stesj8k94dvq-4>li:before{content:"\0025cb "}.lst-kix_63mss7uya7v8-8>li:before{content:"\0025a0 "}.lst-kix_do2cujxbrlc6-3>li:before{content:"\0025cf "}ul.lst-kix_do2cujxbrlc6-0{list-style-type:none}.lst-kix_do2cujxbrlc6-8>li:before{content:"\0025a0 "}.lst-kix_mrkaejkow017-1>li{counter-increment:lst-ctn-kix_mrkaejkow017-1}.lst-kix_uto4kbb3ivor-5>li:before{content:"\0025a0 "}.lst-kix_stesj8k94dvq-6>li:before{content:"\0025cf "}.lst-kix_mrkaejkow017-5>li{counter-increment:lst-ctn-kix_mrkaejkow017-5}ul.lst-kix_do2cujxbrlc6-6{list-style-type:none}ul.lst-kix_do2cujxbrlc6-5{list-style-type:none}ol.lst-kix_m61bwifzx2vm-7.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-7 0}ul.lst-kix_do2cujxbrlc6-8{list-style-type:none}.lst-kix_stesj8k94dvq-7>li:before{content:"\0025cb "}ul.lst-kix_do2cujxbrlc6-7{list-style-type:none}ul.lst-kix_do2cujxbrlc6-2{list-style-type:none}ul.lst-kix_do2cujxbrlc6-1{list-style-type:none}ul.lst-kix_do2cujxbrlc6-4{list-style-type:none}ul.lst-kix_do2cujxbrlc6-3{list-style-type:none}.lst-kix_m61bwifzx2vm-1>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-1,lower-latin) ". "}ol.lst-kix_m61bwifzx2vm-6.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-6 0}.lst-kix_z1o4bed65pky-7>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-7,lower-latin) ". "}ol.lst-kix_y291l4i7csd8-5.start{counter-reset:lst-ctn-kix_y291l4i7csd8-5 0}.lst-kix_z1o4bed65pky-0>li{counter-increment:lst-ctn-kix_z1o4bed65pky-0}.lst-kix_mrkaejkow017-1>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-1,lower-latin) ". "}ol.lst-kix_y291l4i7csd8-6.start{counter-reset:lst-ctn-kix_y291l4i7csd8-6 0}.lst-kix_y291l4i7csd8-5>li{counter-increment:lst-ctn-kix_y291l4i7csd8-5}.lst-kix_m61bwifzx2vm-8>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-8}.lst-kix_z1o4bed65pky-1>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-1,lower-latin) ". "}.lst-kix_m61bwifzx2vm-0>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-0}.lst-kix_uto4kbb3ivor-3>li:before{content:"\0025cf "}.lst-kix_y291l4i7csd8-6>li{counter-increment:lst-ctn-kix_y291l4i7csd8-6}ol.lst-kix_z1o4bed65pky-5.start{counter-reset:lst-ctn-kix_z1o4bed65pky-5 0}.lst-kix_y291l4i7csd8-8>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-8,lower-roman) ". "}.lst-kix_mrkaejkow017-7>li{counter-increment:lst-ctn-kix_mrkaejkow017-7}.lst-kix_uto4kbb3ivor-1>li:before{content:"\0025cb "}ol.lst-kix_m61bwifzx2vm-4.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-4 0}.lst-kix_y291l4i7csd8-2>li{counter-increment:lst-ctn-kix_y291l4i7csd8-2}.lst-kix_stesj8k94dvq-1>li:before{content:"\0025cb "}.lst-kix_y291l4i7csd8-3>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-3,decimal) ". "}.lst-kix_63mss7uya7v8-2>li:before{content:"\0025a0 "}ol.lst-kix_z1o4bed65pky-8.start{counter-reset:lst-ctn-kix_z1o4bed65pky-8 0}ol.lst-kix_m61bwifzx2vm-1.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-1 0}.lst-kix_z1o4bed65pky-1>li{counter-increment:lst-ctn-kix_z1o4bed65pky-1}.lst-kix_y291l4i7csd8-4>li{counter-increment:lst-ctn-kix_y291l4i7csd8-4}.lst-kix_stesj8k94dvq-0>li:before{content:"\0025cf "}.lst-kix_63mss7uya7v8-5>li:before{content:"\0025a0 "}.lst-kix_z1o4bed65pky-6>li{counter-increment:lst-ctn-kix_z1o4bed65pky-6}.lst-kix_stesj8k94dvq-2>li:before{content:"\0025a0 "}ol.lst-kix_mrkaejkow017-3{list-style-type:none}ol.lst-kix_mrkaejkow017-2{list-style-type:none}ol.lst-kix_mrkaejkow017-1{list-style-type:none}ol.lst-kix_mrkaejkow017-0{list-style-type:none}ol.lst-kix_mrkaejkow017-4{list-style-type:none}ol.lst-kix_mrkaejkow017-5{list-style-type:none}.lst-kix_uto4kbb3ivor-8>li:before{content:"\0025a0 "}.lst-kix_y291l4i7csd8-7>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-7,lower-latin) ". "}ol.lst-kix_mrkaejkow017-6{list-style-type:none}ol.lst-kix_mrkaejkow017-7{list-style-type:none}ol.lst-kix_mrkaejkow017-8{list-style-type:none}.lst-kix_z1o4bed65pky-2>li{counter-increment:lst-ctn-kix_z1o4bed65pky-2}.lst-kix_z1o4bed65pky-6>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-6,decimal) ". "}.lst-kix_m61bwifzx2vm-2>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-2,lower-roman) ". "}.lst-kix_m61bwifzx2vm-8>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-8,lower-roman) ". "}ol.lst-kix_z1o4bed65pky-3.start{counter-reset:lst-ctn-kix_z1o4bed65pky-3 0}.lst-kix_z1o4bed65pky-7>li{counter-increment:lst-ctn-kix_z1o4bed65pky-7}.lst-kix_do2cujxbrlc6-7>li:before{content:"\0025cb "}.lst-kix_mrkaejkow017-2>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-2,lower-roman) ". "}ol.lst-kix_y291l4i7csd8-1.start{counter-reset:lst-ctn-kix_y291l4i7csd8-1 0}ol.lst-kix_y291l4i7csd8-2.start{counter-reset:lst-ctn-kix_y291l4i7csd8-2 0}.lst-kix_mrkaejkow017-3>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-3,decimal) ". "}ol.lst-kix_m61bwifzx2vm-5.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-5 0}ol.lst-kix_z1o4bed65pky-6.start{counter-reset:lst-ctn-kix_z1o4bed65pky-6 0}.lst-kix_m61bwifzx2vm-0>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-0,decimal) ". "}.lst-kix_y291l4i7csd8-0>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-0,decimal) ". "}.lst-kix_63mss7uya7v8-1>li:before{content:"\0025cb "}ol.lst-kix_z1o4bed65pky-0.start{counter-reset:lst-ctn-kix_z1o4bed65pky-0 0}.lst-kix_stesj8k94dvq-3>li:before{content:"\0025cf "}.lst-kix_z1o4bed65pky-4>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-4,lower-latin) ". "}.lst-kix_mrkaejkow017-6>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-6,decimal) ". "}ol.lst-kix_mrkaejkow017-4.start{counter-reset:lst-ctn-kix_mrkaejkow017-4 0}.lst-kix_uto4kbb3ivor-2>li:before{content:"\0025a0 "}.lst-kix_63mss7uya7v8-3>li:before{content:"\0025cf "}.lst-kix_mrkaejkow017-0>li{counter-increment:lst-ctn-kix_mrkaejkow017-0}.lst-kix_z1o4bed65pky-0>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-0,decimal) ". "}ol.lst-kix_mrkaejkow017-5.start{counter-reset:lst-ctn-kix_mrkaejkow017-5 0}ol.lst-kix_y291l4i7csd8-6{list-style-type:none}ol.lst-kix_y291l4i7csd8-7{list-style-type:none}ol.lst-kix_m61bwifzx2vm-3.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-3 0}ol.lst-kix_y291l4i7csd8-4{list-style-type:none}ol.lst-kix_m61bwifzx2vm-0.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-0 0}ol.lst-kix_y291l4i7csd8-5{list-style-type:none}ol.lst-kix_y291l4i7csd8-8{list-style-type:none}.lst-kix_z1o4bed65pky-8>li{counter-increment:lst-ctn-kix_z1o4bed65pky-8}ol.lst-kix_y291l4i7csd8-2{list-style-type:none}ol.lst-kix_y291l4i7csd8-3{list-style-type:none}.lst-kix_m61bwifzx2vm-6>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-6}ol.lst-kix_y291l4i7csd8-0{list-style-type:none}ol.lst-kix_y291l4i7csd8-1{list-style-type:none}ul.lst-kix_63mss7uya7v8-3{list-style-type:none}ul.lst-kix_63mss7uya7v8-2{list-style-type:none}ul.lst-kix_63mss7uya7v8-5{list-style-type:none}ul.lst-kix_63mss7uya7v8-4{list-style-type:none}ul.lst-kix_63mss7uya7v8-1{list-style-type:none}ul.lst-kix_63mss7uya7v8-0{list-style-type:none}ul.lst-kix_63mss7uya7v8-7{list-style-type:none}ul.lst-kix_63mss7uya7v8-6{list-style-type:none}.lst-kix_mrkaejkow017-3>li{counter-increment:lst-ctn-kix_mrkaejkow017-3}.lst-kix_z1o4bed65pky-3>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-3,decimal) ". "}ul.lst-kix_63mss7uya7v8-8{list-style-type:none}.lst-kix_do2cujxbrlc6-5>li:before{content:"\0025a0 "}.lst-kix_m61bwifzx2vm-5>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-5}ol.lst-kix_y291l4i7csd8-3.start{counter-reset:lst-ctn-kix_y291l4i7csd8-3 0}.lst-kix_mrkaejkow017-2>li{counter-increment:lst-ctn-kix_mrkaejkow017-2}ol.lst-kix_m61bwifzx2vm-2.start{counter-reset:lst-ctn-kix_m61bwifzx2vm-2 0}.lst-kix_do2cujxbrlc6-0>li:before{content:"\0025cf "}.lst-kix_z1o4bed65pky-5>li{counter-increment:lst-ctn-kix_z1o4bed65pky-5}.lst-kix_y291l4i7csd8-2>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-2,lower-roman) ". "}ol.lst-kix_mrkaejkow017-1.start{counter-reset:lst-ctn-kix_mrkaejkow017-1 0}ol.lst-kix_z1o4bed65pky-2.start{counter-reset:lst-ctn-kix_z1o4bed65pky-2 0}.lst-kix_63mss7uya7v8-6>li:before{content:"\0025cf "}.lst-kix_63mss7uya7v8-4>li:before{content:"\0025cb "}ol.lst-kix_z1o4bed65pky-4.start{counter-reset:lst-ctn-kix_z1o4bed65pky-4 0}ul.lst-kix_stesj8k94dvq-7{list-style-type:none}ul.lst-kix_stesj8k94dvq-8{list-style-type:none}ul.lst-kix_stesj8k94dvq-3{list-style-type:none}ul.lst-kix_stesj8k94dvq-4{list-style-type:none}ul.lst-kix_stesj8k94dvq-5{list-style-type:none}ul.lst-kix_stesj8k94dvq-6{list-style-type:none}ul.lst-kix_stesj8k94dvq-0{list-style-type:none}ul.lst-kix_stesj8k94dvq-1{list-style-type:none}ul.lst-kix_stesj8k94dvq-2{list-style-type:none}ol.lst-kix_mrkaejkow017-7.start{counter-reset:lst-ctn-kix_mrkaejkow017-7 0}.lst-kix_mrkaejkow017-5>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-5,lower-roman) ". "}.lst-kix_y291l4i7csd8-5>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-5,lower-roman) ". "}.lst-kix_m61bwifzx2vm-6>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-6,decimal) ". "}.lst-kix_63mss7uya7v8-0>li:before{content:"\0025cf "}ol.lst-kix_m61bwifzx2vm-4{list-style-type:none}ul.lst-kix_uto4kbb3ivor-8{list-style-type:none}.lst-kix_mrkaejkow017-4>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-4,lower-latin) ". "}ol.lst-kix_m61bwifzx2vm-5{list-style-type:none}ul.lst-kix_uto4kbb3ivor-7{list-style-type:none}ul.lst-kix_uto4kbb3ivor-6{list-style-type:none}ol.lst-kix_m61bwifzx2vm-2{list-style-type:none}ol.lst-kix_m61bwifzx2vm-3{list-style-type:none}ul.lst-kix_uto4kbb3ivor-5{list-style-type:none}.lst-kix_mrkaejkow017-4>li{counter-increment:lst-ctn-kix_mrkaejkow017-4}ol.lst-kix_m61bwifzx2vm-0{list-style-type:none}ol.lst-kix_m61bwifzx2vm-1{list-style-type:none}.lst-kix_mrkaejkow017-0>li:before{content:"" counter(lst-ctn-kix_mrkaejkow017-0,decimal) ". "}.lst-kix_m61bwifzx2vm-7>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-7,lower-latin) ". "}.lst-kix_y291l4i7csd8-3>li{counter-increment:lst-ctn-kix_y291l4i7csd8-3}.lst-kix_uto4kbb3ivor-4>li:before{content:"\0025cb "}.lst-kix_uto4kbb3ivor-6>li:before{content:"\0025cf "}.lst-kix_m61bwifzx2vm-1>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-1}.lst-kix_y291l4i7csd8-4>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-4,lower-latin) ". "}.lst-kix_m61bwifzx2vm-7>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-7}.lst-kix_y291l4i7csd8-8>li{counter-increment:lst-ctn-kix_y291l4i7csd8-8}ol.lst-kix_m61bwifzx2vm-8{list-style-type:none}ol.lst-kix_m61bwifzx2vm-7{list-style-type:none}.lst-kix_m61bwifzx2vm-3>li{counter-increment:lst-ctn-kix_m61bwifzx2vm-3}ol.lst-kix_m61bwifzx2vm-6{list-style-type:none}ol.lst-kix_y291l4i7csd8-7.start{counter-reset:lst-ctn-kix_y291l4i7csd8-7 0}.lst-kix_y291l4i7csd8-7>li{counter-increment:lst-ctn-kix_y291l4i7csd8-7}ol.lst-kix_mrkaejkow017-8.start{counter-reset:lst-ctn-kix_mrkaejkow017-8 0}.lst-kix_uto4kbb3ivor-0>li:before{content:"\0025cf "}ol.lst-kix_mrkaejkow017-6.start{counter-reset:lst-ctn-kix_mrkaejkow017-6 0}.lst-kix_m61bwifzx2vm-5>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-5,lower-roman) ". "}.lst-kix_do2cujxbrlc6-6>li:before{content:"\0025cf "}.lst-kix_stesj8k94dvq-8>li:before{content:"\0025a0 "}.lst-kix_do2cujxbrlc6-2>li:before{content:"\0025a0 "}.lst-kix_63mss7uya7v8-7>li:before{content:"\0025cb "}ul.lst-kix_uto4kbb3ivor-0{list-style-type:none}ol.lst-kix_mrkaejkow017-3.start{counter-reset:lst-ctn-kix_mrkaejkow017-3 0}.lst-kix_uto4kbb3ivor-7>li:before{content:"\0025cb "}ul.lst-kix_uto4kbb3ivor-1{list-style-type:none}ul.lst-kix_uto4kbb3ivor-2{list-style-type:none}ul.lst-kix_uto4kbb3ivor-3{list-style-type:none}ul.lst-kix_uto4kbb3ivor-4{list-style-type:none}ol.lst-kix_z1o4bed65pky-6{list-style-type:none}.lst-kix_z1o4bed65pky-8>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-8,lower-roman) ". "}ol.lst-kix_z1o4bed65pky-5{list-style-type:none}ol.lst-kix_z1o4bed65pky-8{list-style-type:none}ol.lst-kix_z1o4bed65pky-7{list-style-type:none}.lst-kix_mrkaejkow017-8>li{counter-increment:lst-ctn-kix_mrkaejkow017-8}ol.lst-kix_y291l4i7csd8-4.start{counter-reset:lst-ctn-kix_y291l4i7csd8-4 0}ol.lst-kix_z1o4bed65pky-0{list-style-type:none}ol.lst-kix_z1o4bed65pky-2{list-style-type:none}ol.lst-kix_z1o4bed65pky-1{list-style-type:none}ol.lst-kix_z1o4bed65pky-4{list-style-type:none}ol.lst-kix_z1o4bed65pky-3{list-style-type:none}ol.lst-kix_mrkaejkow017-2.start{counter-reset:lst-ctn-kix_mrkaejkow017-2 0}ol.lst-kix_y291l4i7csd8-8.start{counter-reset:lst-ctn-kix_y291l4i7csd8-8 0}.lst-kix_mrkaejkow017-6>li{counter-increment:lst-ctn-kix_mrkaejkow017-6}ol.lst-kix_z1o4bed65pky-7.start{counter-reset:lst-ctn-kix_z1o4bed65pky-7 0}.lst-kix_y291l4i7csd8-1>li{counter-increment:lst-ctn-kix_y291l4i7csd8-1}.lst-kix_m61bwifzx2vm-3>li:before{content:"" counter(lst-ctn-kix_m61bwifzx2vm-3,decimal) ". "}ol.lst-kix_z1o4bed65pky-1.start{counter-reset:lst-ctn-kix_z1o4bed65pky-1 0}.lst-kix_z1o4bed65pky-5>li:before{content:"" counter(lst-ctn-kix_z1o4bed65pky-5,lower-roman) ". "}.lst-kix_y291l4i7csd8-1>li:before{content:"" counter(lst-ctn-kix_y291l4i7csd8-1,lower-latin) ". "}.lst-kix_do2cujxbrlc6-1>li:before{content:"\0025cb "}.lst-kix_z1o4bed65pky-3>li{counter-increment:lst-ctn-kix_z1o4bed65pky-3}ol{margin:0;padding:0}.c2{line-height:1.0;padding-top:52pt;widows:2;orphans:2;direction:ltr;margin-left:-22pt;padding-bottom:12pt;page-break-after:avoid}.c0{padding-left:0pt;line-height:1.6000000238418564;widows:2;orphans:2;direction:ltr;margin-left:36pt;padding-bottom:12pt}.c12{vertical-align:baseline;color:#000000;font-size:11pt;font-style:normal;font-family:"Arial";text-decoration:none;font-weight:normal}.c7{line-height:1.45;widows:2;orphans:2;direction:ltr;padding-bottom:12pt}.c33{line-height:1.0;padding-top:0pt;text-align:left;direction:ltr;padding-bottom:0pt}.c5{widows:2;orphans:2;direction:ltr;page-break-after:avoid}.c26{line-height:1.2;padding-top:11pt;margin-left:-22pt;padding-bottom:12pt}.c6{color:#333333;font-size:52pt;font-family:"Helvetica Neue";font-weight:bold}.c18{padding-left:0pt;line-height:1.0;margin-left:36pt;padding-bottom:12pt}.c1{color:#333333;font-size:12pt;font-family:"Helvetica Neue";font-weight:bold}.c15{line-height:1.2;padding-top:13pt;margin-left:-22pt;padding-bottom:12pt}.c13{color:#333333;font-size:10pt;background-color:#f7f7f7;font-family:"Verdana"}.c42{max-width:468pt;background-color:#ffffff;padding:72pt 72pt 72pt 72pt}.c20{color:#333333;font-size:20pt;font-family:"Helvetica Neue"}.c8{widows:2;orphans:2;direction:ltr}.c23{line-height:1.0;margin-left:18pt;padding-bottom:0pt}.c14{line-height:1.0;margin-left:54pt;padding-bottom:0pt}.c32{line-height:1.2;padding-top:52pt;padding-bottom:12pt}.c19{font-size:10pt;background-color:#f7f7f7;font-family:"Verdana"}.c37{line-height:1.0;margin-left:36pt;padding-bottom:0pt}.c35{color:#4183c4;font-size:12pt;font-family:"Helvetica Neue"}.c27{color:#333333;font-size:10pt;font-family:"Verdana"}.c4{color:#333333;font-size:12pt;font-family:"Helvetica Neue"}.c40{color:#333333;font-size:30pt;font-family:"Helvetica Neue"}.c31{padding-left:0pt;margin-left:72pt;padding-bottom:12pt}.c3{color:#1155cc;text-decoration:underline}.c34{color:#333333;font-size:12pt}.c9{color:inherit;text-decoration:inherit}.c36{padding-left:0pt;margin-left:36pt}.c16{line-height:1.6000000238418564;padding-bottom:12pt}.c30{margin:5px;border:1px solid black}.c29{margin-left:-22pt;padding-bottom:12pt}.c22{line-height:1.0;padding-top:17pt}.c38{line-height:1.0;padding-bottom:0pt}.c24{margin:0;padding:0}.c41{height:14pt}.c28{font-family:"Anonymous Pro"}.c10{font-style:italic}.c21{height:12pt}.c39{line-height:1.6000000238418564}.c25{line-height:1.45}.c11{font-family:"Times New Roman"}.c17{font-weight:bold}.title{widows:2;padding-top:0pt;line-height:1.6000000238418564;orphans:2;text-align:left;color:#333333;font-size:21pt;font-family:"Trebuchet MS";padding-bottom:0pt;page-break-after:avoid}.subtitle{widows:2;padding-top:0pt;line-height:1.6000000238418564;orphans:2;text-align:left;color:#666666;font-style:italic;font-size:13pt;font-family:"Trebuchet MS";padding-bottom:10pt;page-break-after:avoid}li{color:#333333;font-size:12pt;font-family:"Helvetica Neue"}p{color:#333333;font-size:12pt;margin:0;font-family:"Helvetica Neue"}h1{widows:2;padding-top:52pt;line-height:1.0;orphans:2;text-align:left;color:#333333;font-size:52pt;font-family:"Helvetica Neue";font-weight:bold;padding-bottom:12pt;page-break-after:avoid}h2{widows:2;padding-top:17pt;line-height:1.0;orphans:2;text-align:left;color:#333333;font-size:30pt;font-family:"Helvetica Neue";font-weight:bold;padding-bottom:12pt;page-break-after:avoid}h3{widows:2;padding-top:13pt;line-height:1.2;orphans:2;text-align:left;color:#333333;font-size:20pt;font-family:"Helvetica Neue";font-weight:bold;padding-bottom:12pt;page-break-after:avoid}h4{widows:2;padding-top:11pt;line-height:1.2;orphans:2;text-align:left;color:#333333;font-size:14pt;font-family:"Helvetica Neue";font-weight:bold;padding-bottom:12pt;page-break-after:avoid}h5{widows:2;padding-top:8pt;line-height:1.6000000238418564;orphans:2;text-align:left;color:#666666;font-size:11pt;font-family:"Trebuchet MS";padding-bottom:0pt;page-break-after:avoid}h6{widows:2;padding-top:8pt;line-height:1.6000000238418564;orphans:2;text-align:left;color:#666666;font-style:italic;font-size:11pt;font-family:"Trebuchet MS";padding-bottom:0pt;page-break-after:avoid}</style></head><body class="c42"><p class="c8 c38 c21"><span></span></p><p class="c8 c23"><span class="c3"><a class="c9" href="#h.2h1pi445crfr">Goals</a></span></p><p class="c8 c23"><span class="c3"><a class="c9" href="#h.34ym527j5fvc">Core Principles</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.9nnain5lptm6">Filter (System)</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.n3fbme3wgat">Focus</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.j6szak26o6hq">Parsing</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.mrcma59xcci4">Combined System</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.v2tmwsah1cll">Examples</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.z3l91u5bc41">Reasoning</a></span></p><p class="c8 c23"><span class="c3"><a class="c9" href="#h.l1t3mkcvgxaz">Further ideas</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.6ycxkapm15oc">Natural Language Processing</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.wk39xd2g9kt7">UI</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.31ctnkzaxyar">Architecture</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.xopm62zdzsw9">Microservices</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.hfgw0spdtfx2">Attributes of Instruments</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.ak3aq985u8f5">Non Dimmer Types</a></span></p><p class="c8 c37"><span class="c3"><a class="c9" href="#h.b0szat40fiav">Modifying Existing Levels</a></span></p><p class="c8 c14"><span class="c3"><a class="c9" href="#h.hm7dvkn2t4l0">Cues</a></span></p><p class="c8 c23"><span class="c3"><a class="c9" href="#h.4manql56efss">FAQ</a></span></p><p class="c8 c21 c38"><span></span></p><hr style="page-break-before:always;display:none;"><p class="c8 c38 c21"><span></span></p><h1 class="c5 c32"><a name="h.2h1pi445crfr"></a><span class="c6">Goals</span></h1><ul class="c24 lst-kix_do2cujxbrlc6-0 start"><li class="c0"><span>Simple</span></li></ul><ul class="c24 lst-kix_do2cujxbrlc6-1 start"><li class="c8 c31"><span class="c4">UI should be intuitive. If you know lighting, you should be able to walk up and start creating.</span></li></ul><ul class="c24 lst-kix_do2cujxbrlc6-0"><li class="c0"><span class="c4">Does what we need</span></li><li class="c0"><span class="c4">Extensible (for anyone)</span></li></ul><h1 class="c5"><a name="h.34ym527j5fvc"></a><span>Core Principles</span></h1><p class="c8"><span>Terms (code example for illustration in Go):</span></p><ul class="c24 lst-kix_stesj8k94dvq-0 start"><li class="c18 c8"><span class="c17">DMX </span><span class="c1">Address</span><span>: The position of a single </span><span class="c3"><a class="c9" href="http://www.google.com/url?q=http%3A%2F%2Ftsp.plasa.org%2Ftsp%2Fdocuments%2Fdocs%2FE1-11_2008R2013.pdf&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNEcM1mkwKiMJUzmsC2gD_EBhLmMcw">DMX data slot</a></span><span>. We are assuming only </span><span>one universe</span><span>&nbsp;to begin with, because that is what I am familiar with. I am open to expanding to multiple, if someone else can help me understand the nuances of exporting to multiple universes. So this is limited to 1-512 currently, using one universe. </span><span>Previously I (incorrectly/lazily) called this the </span><span class="c10">dimmer number</span><span>.</span><span><br></span><span class="c28">type DMXAddress int</span></li><li class="c18 c8"><span class="c17">DMX Value</span><span>: The byte (integer between 0-255) sent at a certain DMX address. This can be thought of as the resulting </span><span class="c10">level</span><span>&nbsp;if it controls a lighting instrument. In that case it usuallydisplayed as a percentage and converted into a DMX value later, </span><span>losing precision</span><span>.<br></span><span class="c28">type DMXValue uint8</span></li><li class="c18 c8"><span class="c17">Patch</span><sup><a href="#cmnt1" name="cmnt_ref1">[a]</a></sup><sup><a href="#cmnt2" name="cmnt_ref2">[b]</a></sup><sup><a href="#cmnt3" name="cmnt_ref3">[c]</a></sup><sup><a href="#cmnt4" name="cmnt_ref4">[d]</a></sup><span>: Provides a key-value store for each DMX address, providing a minimally complete description of the resulting hardware they control. For example, it could contain DMX address 12 patched to the key-value store of {position: front, color: warm, use: green}. No keywords are required and any number can be created by users. This serves a similar function to a patch on an ETC Express board, but maps address-&gt;attributes instead of channel-&gt;address<br></span><span class="c28">type PatchKey string<br>type PatchValue string</span><span><br></span><span class="c28">type Patch map[DMXAddress]map[PatchKey][PatchValue]</span></li><li class="c18 c8"><span class="c17">S</span><span class="c1">ystem</span><span class="c4">: </span><span>Any abstraction that can be resolved to a map of DMX addresses to DMX values.</span><span class="c4">&nbsp;In terms of an ETC Eos Palettes, Presets, Cues, Channels, Groups, and Submasters would all have a component of them that was a </span><span class="c4">system</span><span class="c4">, even if they stored other information as well.</span><span class="c4"><br></span><span class="c34 c28">DMXData </span><span class="c28">map[DMXAddress]DMXValue</span><span class="c28 c34"><br>type System interface {</span><span class="c28"><br></span><span class="c34 c28">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c28">DMXData</span><span class="c34 c28">() </span><span class="c28">DMXData<br></span><span class="c34 c28">}</span></li><li class="c8 c18"><span class="c17">Combined System</span><span>: Multiple systems that are merged together is itself a system. They ordered, so the merge happens by Last Takes Precedence.<br></span><span class="c28">type CombinedSystem struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Systems []System<br>}<br>func (cs *CombinedSystem) DMXData() DMXData {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dd = make(DMXData)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for s := range(cs.Systems) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mergeMap(*dd, s.DMXData())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return dd<br>}</span></li><li class="c0"><span class="c17">Look</span><span>: A </span><span class="c10">combined system</span><span>&nbsp;with a label associate with it. This is the same as a submaster or group on an ETC Express</span></li><li class="c0"><span class="c17">Filter</span><span>: A system that is build from live filtering all patched addresses, that fit a certain filter. Say all that have attribute &ldquo;type&rdquo; set to &ldquo;front&rdquo;.</span></li><li class="c0"><span class="c17">State</span><span>: A unique </span><span class="c10">combined system</span><span>&nbsp;that is outputted to the DMX hardware. This is displayed to the user as well.</span></li><li class="c0"><span class="c17">Cue</span><span>: A </span><span class="c10">combined system</span><span>&nbsp;that has associated data for timing, labeling, and ordering.</span></li></ul><h2 class="c5"><a name="h.9nnain5lptm6"></a><span>Filter (System)</span></h2><p class="c8"><span>Filters are the primary way you will build your looks. Right now I am looking at it as if each address has certain attributes, and if we can just write down each of the attributes, then we can query based on them. &nbsp;</span></p><h3 class="c5"><a name="h.n3fbme3wgat"></a><span>Focus</span></h3><p class="c8 c16"><span>They are a relatively simple system, but the hard part will be accommodating the natural language around how we describe them. For example, if we say &ldquo;USL&rdquo;, we actually looking two attributes. Lights with the US-DS position set to US and the left-righ position set to Left. </span><span class="c4">As long as you don&#39;t have more than five zones, we can parse these names. It is really two attributes here, the US-DS position and the SL-SR position. Is there a name for those two axis? Width and depth? I think the best thing to do is to store these separately, sort of like storing the x and y coordinate. So they would be called something like </span><span class="c1">focus_vertical</span><span class="c4">&nbsp;and </span><span class="c1">focus_horizontal</span><span class="c4">. However, this assumes some very normalized positions. What if you have a special on the &quot;US Couch&quot;? Well I would argue that we need a </span><span class="c1">focus</span><span class="c4">&nbsp;keyword as well, that would hold &quot;couch&quot;.</span></p><p class="c8 c16"><span class="c4">This all makes sense in an ideal world, but shows are not going to be like this all the time. We need room for flexibility. So obviously these keywords shouldn&#39;t be fixed. The user needs some way of saying &quot;Hey I actually have my own keywords&quot;. What would be great is if all this logic could be edited </span><span class="c4 c10">by</span><span class="c4">&nbsp;the user. It might end up being too complicated for that, but that would be ideal. Then they could decide how to interpret positions and all that.</span></p><h3 class="c5 c26"><a name="h.j6szak26o6hq"></a><span>Parsing </span></h3><p class="c8"><span>We also need to figure out how we interpret use input that has a mixing of attributes, that are all unlabeled. For example, if the user types in &quot;USL Front warm @ full&quot;, how do we know what attributes come out of this query? How do we know &quot;warm&quot; is a </span><span>color</span><span>&nbsp;and &quot;front&quot; is the </span><span>use</span><span>? Well we have a couple of options (that I see):</span></p><ol class="c24 lst-kix_mrkaejkow017-0 start" start="1"><li class="c0"><span class="c4">Since we know the patch already, we can go through inputted word and see if it exists in any of the patched attributes. So when tell it &quot;Front&quot;, it will look </span><span class="c4">through all the values of every attribute for all lights</span><span class="c4">&nbsp;and see that &quot;Front&quot; appears only as a </span><span class="c27">use</span><span class="c4">, so will categorize it like that. </span><span class="c4">Problems would come up if there were the same values present for multiple attributes (which could be resolved by restricting this when they are adding them).</span><span class="c4">&nbsp;Also, could be a bit slow. It&#39;s nice that it allows flexible ordering, however. And the speed could be remedied by pre-computing that mapping of attributes values to attribute keys.</span></li><li class="c0"><span class="c4">We could allow the user to specify a consistent ordering that they use. For example, this could be </span><span class="c27">position use color</span><span class="c4">. So then if they wrote &quot;USL front warm&quot;, it would know which input words match with which attributes. However, a problem with this design is that it is stricter, so is worse for the user to use. Also, you are going to have optional keywords, so how does it know which ones you input?</span></li><li class="c0"><span class="c4">Something for advanced use natural language machine learning.</span></li></ol><h2 class="c5 c22 c29"><a name="h.mrcma59xcci4"></a><span>Combined System</span></h2><p class="c8 c16"><span class="c4">To combine systems you order them in a stack and merge them all together, </span><span class="c4">where the top (or bottom depending on preference and user testing) of the stack</span><span class="c4">&nbsp;takes precedence. </span><span class="c4">Later systems that are added will have priority.</span></p><h3 class="c5 c15"><a name="h.v2tmwsah1cll"></a><span class="c20">Examples</span></h3><p class="c8 c16"><span class="c4">For example, let&#39;s say your stack looked like this:</span></p><p class="c7"><span class="c13">* Dimmer 10 @ 25%<br>* Dimmer 10 @ 50%<br>* Dimmer 3 @ 50%<br></span></p><p class="c8 c16"><span class="c4">Here the final state would be dimmer 10 @ 25% and dimmer 3 @ 50%.</span></p><p class="c8 c16"><span class="c4">In a more realistic example:</span></p><p class="c7"><span class="c13">* Front USC W @ 30%<br>* Front W @ 78%<br>* Cue 1<br></span></p><p class="c8 c16"><span class="c4">Cue 1 is made from:</span></p><p class="c7"><span class="c13">* Front W @ 50%<br>* Front C @ 25%<br>* Top @ 30%<br></span></p><p class="c8 c16"><span class="c4">So all together the final state will be equivalent to top @ 30%, front C @ 25%, all front warm besides the USC @ 78%, and the USC front warm @ 30%.</span></p><h3 class="c5 c15"><a name="h.z3l91u5bc41"></a><span class="c20">Reasoning</span></h3><ol class="c24 lst-kix_m61bwifzx2vm-0 start" start="1"><li class="c0"><span class="c4">It is easy for the operator to </span><span class="c4">answer </span><span class="c4 c10">why</span><span class="c4">&nbsp;levels are at where they are</span><span class="c4">, long after they have been recorded.</span></li><li class="c0"><span class="c4">The stack based approach is unambiguous and uniform, eliminating the need for capturing or different ordering approaches.</span></li></ol><h1 class="c5"><a name="h.l1t3mkcvgxaz"></a><span>Further ideas</span></h1><h2 class="c5"><a name="h.6ycxkapm15oc"></a><span>Natural Language Processing</span></h2><p class="c8 c16"><span class="c35"><a class="c9" href="https://www.google.com/url?q=https%3A%2F%2Fwww.talater.com%2Fannyang%2F&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFiWWgwiChdyufBS-0eNh6CaYbMuw">Annyang</a></span><span class="c4">&nbsp;provides a way to take human typed text + speech input and get actions out of it. So you can train it with things like &quot;When I say &#39;bring up dimmer 10&#39; I want you to do </span><span class="c27">{system: dimmmer, number: 10, level: 100}</span><span class="c4">&quot;. This means we can just add on language processing on top of the standard way of bringing up dimmers</span></p><ul class="c24 lst-kix_uto4kbb3ivor-0 start"><li class="c0"><span class="c4">&quot;Bring dimmer 10 up to full&quot;</span></li><li class="c0"><span class="c4">&quot;Record dimmer 10 as USL front warm&quot;</span></li><li class="c0"><span class="c4">&quot;Bring the front cools to full&quot;</span></li><li class="c0"><span class="c4">&quot;What are the USL front warms at?&quot;</span></li></ul><h2 class="c5"><a name="h.wk39xd2g9kt7"></a><span>UI</span></h2><p class="c8"><span>Things we need in UI:</span></p><ol class="c24 lst-kix_z1o4bed65pky-0 start" start="1"><li class="c8 c36"><span>Some way to see all dimmers up ( or lights by filter) and what they are from</span></li><li class="c8 c36"><span>Cue list (and diffs)</span></li><li class="c8 c36"><span>Find lights in cues</span></li><li class="c8 c36"><span>Current State</span></li><li class="c8 c36"><span>Patch (set attributes of dimmers)</span></li><li class="c8 c36"><span>Colors (may be same as patch)</span></li></ol><h4 class="c5 c41"><a name="h.gn2irfq731ul"></a></h4><p class="c8 c16"><span class="c4">I know it will have to contain the current state, as a list of systems that are up. There should also be a way to drill down into a system,</span><span class="c4">&nbsp;maybe by clicking on it</span><span class="c4">. Then you can see what it is made up of. A cascading list/tree type thing might be right here. Like for Reddit. Could filter down all the way to DMX values of addresses. Would also have to support moving lights out of groups, and creating groups, in the UI. Great by drag and drop somehow. </span></p><p class="c8 c16"><span class="c4">Also there are a multiple ways of viewing many of the systems, the human readable notation (&quot;US Front&quot;) and the actual representation </span><span class="c27">{position: &quot;up&quot;, use: &quot;front&quot;}</span><span class="c4">. I think the human readable should be displayed by default and can be parsed into the actual representation, but the more precise notation should be easily accessible if you hover over or click or something.</span></p><p class="c8 c16"><span class="c4">If you hover over any percentage, or click on it, you should be able to modify it with the scroll wheel + keypress or keyboard.</span></p><h2 class="c5"><a name="h.31ctnkzaxyar"></a><span>Architecture</span></h2><p class="c8 c16"><span class="c4">No lighting systems that I know of use HTTP and web technologies to create their interfaces. All that I know of render the UI locally on whatever machine they are running on.</span></p><p class="c8 c16"><span class="c4">However, I think using HTTP does present some advantages:</span></p><ol class="c24 lst-kix_y291l4i7csd8-0 start" start="1"><li class="c0"><span class="c4">Access on any device/cross platform</span></li><li class="c0"><span class="c4">CSS is arguably most used layout system ever created. This means tons of libraries to build from, as well as plenty of examples.</span></li><li class="c0"><span class="c4">The same goes for JS.</span></li><li class="c0"><span class="c4">Server software can potentially be run on very cheap hardware, just serving up HTTP server (with language of choice).</span></li><li class="c0"><span class="c4">Networking is incredibly advanced + cheap for HTTP, based on its reliance on TCP/IP. This means we get wireless connections for free.</span></li></ol><p class="c8 c16"><span class="c4">Another disadvantage is unreliable performance. I think most of the variability here is from network level latency, not the unpredictability of the application. Well, we have control over the performance of the client and server code, but less control over the network, which is worrying. I have not done any testing yet of performance characteristics under different network conditions, but I assume that using a dedicated network for lighting is the simplest way to alleviate fears of other devices creating latency.</span></p><p class="c8 c16"><span class="c4">For a look at some of the current options, check out the </span><span class="c35"><a class="c9" href="https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fsaulshanabrook%2Flighting%2Fblob%2Fmaster%2Fdocs%2Farchitecture.md&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNHcoQZssMmyOVy34bP3cHsBK2IEDA">./architecture.md</a></span><span class="c4">&nbsp;file.</span></p><h3 class="c5"><a name="h.xopm62zdzsw9"></a><span>Microservices</span></h3><p class="c8"><span>Since we the user will be interacting with the system in their browser, a lot of logic needs to be on the client side (which means in their browser). It is a good idea to minimize duplicating logic, so we should attempt to do eliminate as much logic as possible from the server, since it will need to already exist in the client. The only reason we need a server in the first place is to &ldquo;render&rdquo; the DMX output to USB and to persist our data between browser and sessions.</span></p><p class="c8"><span>We can split up these needs. Persisting the data is orthogonal to rendering the current state, so we can create two separate systems. This is mockup of how the architecture will function:</span></p><p class="c8"><span style="overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 508.00px; height: 393.00px;"><img alt="TL5DRy8m3BtxLrYSw84_CA69Znx60QaQ824X3bvgZKXjgHmN3eZ_ZhEeWqvQBadUU_PxJcP1IRIhAm3rMZ7EnPsyijDE6034JjHy6p7wvAPamGtBnJiUuGtGrdXUh3AaW4AjJyYo4-56CVTr7GkKb7yahWn9aLgnP70VM1GimLkYnl6_FkslJqvANnJuRvU5dA-1fQyyB2jlSOvH1OTylJ_QdZ2SJYRlE8xHCtp3Z-ss63BjAnCl2U-T8LQY0JQPgQvYBnUWd-v925Cvn2s6uRlDmhB0p0ZxWWS0" src="images/image00.png" style="width: 508.00px; height: 393.00px; margin-left: 0.00px; margin-top: 0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></p><p class="c8"><span class="c3"><a class="c9" href="http://www.google.com/url?q=http%3A%2F%2Ftextuploader.com%2Fxz94&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNEsX3GNryvbkZ5n9tbQ2S19e90kDw">http://textuploader.com/xz94</a></span></p><p class="c8"><span>It seems fine to use Python for the Render service, because </span><span class="c3"><a class="c9" href="https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fsaulshanabrook%2Flighting%2Ftree%2Fmaster%2Ftesting-architectures%23resaults&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGn1R30io8ztY4jE0E4P1VNCxwYdw">I did some benchmarking</a></span><span>&nbsp;and found response times of parsing and sending back json to be &lt;5ms for a server.</span></p><p class="c8 c21"><span></span></p><h2 class="c5"><a name="h.hfgw0spdtfx2"></a><span>Attributes of Instruments</span></h2><p class="c8 c16"><span class="c4">Major complications arise when considering multi parameter fixtures, for example moving lights, color scrollers, mirrors, and gobo rotators.</span></p><p class="c8 c16"><span class="c4">While these would all function fine under the above proposed system the workflow could be a bit ugly.</span></p><p class="c8 c16"><span class="c4">For example, let&#39;s say you have a bunch of backlight with color scrollers on them.</span></p><p class="c8 c16"><span class="c4">Let&#39;s say your patch looks like this:</span></p><p class="c7"><span class="c13">{<br> &nbsp; &nbsp;1: {use: back, pos: left, </span><span class="c19">type</span><span class="c13">: </span><span class="c19">dimmer</span><span class="c13">}<br> &nbsp; &nbsp;2: {use: back, pos: center, </span><span class="c19">type</span><span class="c13">: </span><span class="c19">dimmer</span><span class="c13">}<br> &nbsp; &nbsp;3: {use: back, pos: right, </span><span class="c19">type</span><span class="c13">: </span><span class="c19">dimmer</span><span class="c13">}<br> &nbsp; &nbsp;</span><span class="c13">101</span><span class="c13">: {use: back, pos: left, </span><span class="c19">type</span><span class="c13">: color}<br> &nbsp; &nbsp;102: {use: back, pos: center, </span><span class="c19">type</span><span class="c13">: color}<br> &nbsp; &nbsp;102: {use: back, pos: right, </span><span class="c19">type</span><span class="c13">: color}<br>}<br></span></p><p class="c8 c16"><span class="c4">Then one way to bring up the lights would be to address them separately</span></p><p class="c7"><span class="c13">* Back Color @ </span><span class="c19">125</span><span class="c13"><br>* Back </span><span class="c13">@ 50%</span><span class="c13"><br></span></p><p class="c8 c16"><span class="c4">This will translate to two filter systems. We can assume that when you don&#39;t specify an </span><span class="c19">type</span><span class="c4">&nbsp;you mean </span><span class="c19">dimmer</span><span class="c4">.</span></p><p class="c8 c16"><span class="c4">While this works, </span><span>it would be nice to see this as one line, since this is really describing one set of lights, like this:</span></p><p class="c7"><span class="c13">* Back @ 50%, Color @ </span><span class="c19">125</span></p><p class="c8 c16"><span>To get this sort of behavior, we could create a </span><span class="c10">look</span><span>&nbsp;with the previous two filters in it. So ours state would just have this one look in it, and inside the look would be both of our </span><span class="c10">filters</span><span>. Then, when displaying our state, we could look inside the </span><span class="c10">look</span><span>&nbsp;and see that both of it&rsquo;s systems are </span><span class="c10">filters</span><span>&nbsp;that share all keys besides </span><span class="c28">type</span><span class="c11">&nbsp;</span><span>(One is &ldquo;color&rdquo; and the other &ldquo;dimmer&rdquo;). &nbsp;So it would display the level of each, in one line, but we could expand this into two filters, just like any other combined system.</span></p><p class="c8 c16 c21"><span class="c4"></span></p><h3 class="c5"><a name="h.ak3aq985u8f5"></a><span>Non Dimmer </span><span>Types</span></h3><p class="c8 c16"><span class="c4">Another question is how to properly implement things like color and mirror control. I think the UI to the user is pretty clear in some cases.</span></p><p class="c7"><span class="c13">* Back Color @ Green # alias for </span><span class="c19">125</span><span class="c13"><br>* US Mirror Control @ (13%, 20%)<br>* DS Mirror Control @ Center Stage # this would be an alias for a coordinate<br>* Side Strip Color @ (10%, 30%, 50%) # these would be RGB levels, </span><span class="c13">hovering over should allow color wheel selection</span><span class="c13"><br></span></p><h4 class="c5 c25"><a name="h.oly82l2579mt"></a><span>Multiple Address Attributes</span></h4><p class="c8"><span>If we look at a mirror, it really has two attributes, pan and tilt. So we could store that in the patch as another attribute</span></p><p class="c8"><span class="c19">{<br> &nbsp; &nbsp;1: {use: front, pos: center, type: dimmer}<br> &nbsp; &nbsp;</span><span class="c19">101</span><span class="c19">: {use: front, pos: center, type: mirror, orientation: pan}<br> &nbsp; &nbsp;102: {use: front, pos: center, type: mirror, orientation: tilt}<br>}</span></p><h4 class="c5 c25"><a name="h.12qvya3t1sig"></a><span>Color Mappings</span></h4><p class="c8 c16"><span class="c4">The first example requires the system to know that for that particular color scroller, &quot;green&quot; </span><span class="c4">is </span><span class="c19">125</span><span class="c4">. So this in turn requires mapping certain lights to what physical instrument they are. For example, we know, in this example, that dimmers 101-103 are color scrollers with a green color at level </span><span class="c19">125</span><span class="c4">.</span></p><p class="c8 c16"><span class="c4">We could just have a map of dimmer numbers to their profile, but that seems a bit messy. This would like like: {1: Scroller, 5: Scroller, 10: Mirror, 11: mirror}</span></p><p class="c8 c16"><span class="c4">This is messy because it isn&#39;t really the </span><span class="c4 c10">dimmer number</span><span class="c4">&nbsp;that is that instrument but the label. </span><span class="c4">Even if the the dimmer number of that scroller changes, it will still be called the Back Color. So let&#39;s make up a new interface,</span></p><p class="c8 c16"><span class="c4">Profile/Instrument Type OK lets do that:</span></p><p class="c8 c16"><span class="c1">TODO</span><span class="c4">: Figure out exactly how this interface will work, how mapping works between this instrument patch and the other patch</span></p><h2 class="c5 c22"><a name="h.b0szat40fiav"></a><span>Modifying Existing Levels</span></h2><p class="c8 c16"><span class="c4">Often times we don&#39;t care about the absolute level of a light, we just want it to be a bit more than it already is. One way to do this is just to capture the light higher than it is currently. However, I think it would be more powerful to be able to create relative levels.</span></p><p class="c8 c16"><span class="c4">For examples if we have</span></p><p class="c7"><span class="c13">Warm Indoor <br></span></p><p class="c8 c16"><span class="c4">And we want to make it a bit cooler, it would be nice if we could do</span></p><p class="c7"><span class="c13">Front Cools +@ 10%<br>Warm Indoor <br></span></p><p class="c8 c16"><span class="c4">Which will increase whatever level the is previously. I think this is preferable for a few reasons.</span><span class="c4">&nbsp;First it is more obvious what our intention was.</span><span class="c4">&nbsp;Coming back to look at this cue later, it is obvious what we wanted to do. If we had set it to an absolute level instead, we would have to do some more digging, before we knew what we were trying to do. Also, if we have and modify </span><span class="c27">Warm Indoor</span><span class="c4">&nbsp;later, it will still be a bit cooler in this scene.</span></p><p class="c8 c16"><span class="c4">If we include </span><span class="c27">@+</span><span class="c4">&nbsp;it would also make sense to have </span><span class="c27">@-</span><span class="c4">, </span><span class="c27">@*</span><span class="c4">, and </span><span class="c27">@/</span><span class="c4">.</span></p><p class="c8 c16"><span class="c4">So we have to make sure of a few things. First that these only work with the numeric type of levels. It doesn&#39;t make sense (so shouldn&#39;t be allowed) to += a color...</span></p><p class="c8"><span>Another idea is to have some sort of &ldquo;ON&rdquo; keyword so you could do, &ldquo;Fronts ON @+ 10%&rdquo; so that it would only increase those not at zero. </span></p><h3 class="c5 c29 c22"><a name="h.hm7dvkn2t4l0"></a><span>Cues</span></h3><p class="c8 c16"><span class="c1">TODO</span><span class="c4">: Try to understand best way of </span><span class="c4">cueing</span><span class="c4">, and different timings needed. Look at existing systems out there. </span><span class="c4">Basic timings include upfade and downfade.</span><sup><a href="#cmnt5" name="cmnt_ref5">[e]</a></sup><span class="c4">&nbsp;Do we wanna just copy the simplest model? Like the standard? Or are there ways we can make it simpler?</span></p><p class="c8 c16 c21"><span class="c4"></span></p><p class="c8 c16"><span class="c4">Do we want a graphical thing like Vista?</span></p><h1 class="c2"><a name="h.4manql56efss"></a><span class="c6">FAQ</span></h1><p class="c8 c16"><span class="c4">Q: </span><span class="c4 c10">But the Eos family board already has this type of abstraction with Presets and </span><span class="c4 c10">Pallets</span><span class="c4 c10">.</span></p><p class="c8 c16"><span class="c4">A: While they do allow this same type of abstraction,</span><span>&nbsp;it is built on top of their existing notion of channels. </span><span class="c4">In this system, there are </span><span class="c4">no channels</span><span class="c4">. This allows </span><span>us to put the abstractions front and center as </span><span class="c10">the</span><span>&nbsp;way to select lights. </span><span class="c4">Also the difference of the stack based system means that it is clearer what the current state is made up of.</span></p><p class="c8 c16"><span class="c4">Q: </span><span class="c4 c10">Touchscreens suck.</span></p><p class="c8 c16"><span class="c4">A: Yep I agree. Manual sliders are nicer for manual control and channel setting. It is a question of trade offs. The benefit of this system is not that it is digital, but that by starting from scratch we can implement different data schemes. I would love to add support for hardware, or even dedicated hardware, but that is a secondary priority right now.</span></p><p class="c8 c16"><span class="c4">Q: </span><span class="c4 c10">This will be less reliable, because it is not on a dedicated machine.</span></p><p class="c8 c16"><span class="c4">A: So this is a complicated one to answer, because it&#39;s reliability is mainly based on what the codebase looks like and how much use it has gotten. While it will likely be less popular than other systems, there is nothing fundamental stopping it from being just as reliable. I see this as running on a stripped down linux box that only runs this app. The reliability of the system would be comparable to the reliable of any linux based server.</span></p><p class="c8 c16"><span class="c4">Q: </span><span class="c4 c10">You can&#39;t please everyone, this doesn&#39;t address the concerns of x.</span></p><p class="c8 c39"><span class="c4">A: Fundamentally I am writing this to scratch </span><span class="c4 c10">my</span><span class="c4">&nbsp;itch not yours. I am totally open to other perspectives and wants, as long as they don&#39;t fundamentally alter the premise that allows me to get what I want out of it and don&#39;t add unneeded complexity.</span></p><p class="c8 c21"><span></span></p><div class="c30"><p class="c33"><a href="#cmnt_ref1" name="cmnt1">[a]</a><span class="c12">How will this system handle attributes on a fixture that use two DMX slots?</span></p></div><div class="c30"><p class="c33"><a href="#cmnt_ref2" name="cmnt2">[b]</a><span class="c12">Refer to the data example under this header: https://docs.google.com/document/d/1jG8WOEXdV38uYForhkKiPiaaucBWEZGXvqL7K_A3osY/edit#heading=h.hfgw0spdtfx2</span></p></div><div class="c30"><p class="c33"><a href="#cmnt_ref3" name="cmnt3">[c]</a><span class="c12">I mean individual attributes, such as pan or tilt over two slots.</span></p></div><div class="c30"><p class="c33"><a href="#cmnt_ref4" name="cmnt4">[d]</a><span class="c12">Oh I see. Good question. I think another key-value on that address. Ill add an example below</span></p></div><div class="c30"><p class="c33"><a href="#cmnt_ref5" name="cmnt5">[e]</a><span class="c12">There is more than that. You may skip advanced timing functions like dedicated or fanned timing down to channel level, but you definitely should not omit delay to both upfade and downfade and consider wait/follow timing.</span></p></div></body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment