--- /dev/null
+How to prepare:
+
+ Copy all .html and .png files into your CasparCG templates/ directory.
+ Copy casparcg.config into your CasparCG directory. cd into client/
+ and run make to compile the client.
+
+How to run:
+
+ 1. rm /tmp/caspar.sock.
+ 2. Run CasparCG. It will hang until Nageru connects.
+ 3. Start Nageru with -c 3 -t ultimate.lua.
+ 4. Start the client.
+ 5. Switch to channel 5 and turn on the overlay when it's started.
+
+If you need to restart CasparCG for any reason, you'll need to redo steps 1 and 2
+in order. Nageru and the client can stay up; they will reconnect automatically.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg11445"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bg.svg">
+ <defs
+ id="defs11439">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient12837">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop12833" />
+ <stop
+ style="stop-color:#f3f3f3;stop-opacity:0.95686275"
+ offset="1"
+ id="stop12835" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient758"
+ spreadMethod="pad"
+ gradientTransform="matrix(1041.9775,0,0,-1041.9775,1161.687,5231.604)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop12314"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ffffff" />
+ <stop
+ id="stop12316"
+ offset="0.10691959"
+ style="stop-opacity:1;stop-color:#ffffff" />
+ <stop
+ id="stop12318"
+ offset="1"
+ style="stop-opacity:1;stop-color:#231f20" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath750">
+ <path
+ d="m 1405.364,5194.503 c -50.371,-43.444 -89.981,-61.977 -127.217,-61.319 -26.092,0.466 -51.105,10.931 -75.785,31.831 8.139,-14.917 19.583,-32.813 34.809,-50.074 20.852,-23.635 44.648,-41.487 70.716,-53.059 32.528,-14.439 68.85,-19.132 107.953,-13.948 89.028,11.79 239.813,79.55 283.148,163.123 l 4.079,7.872 6.725,-5.78 c 71.402,-61.345 236.579,-67.907 323.568,-45.6 37.707,9.668 69.318,27.248 93.953,52.243 42.102,42.724 55.918,99.005 60.318,135.999 -15.08,-28.557 -34.359,-47.574 -58.362,-57.734 -50.856,-21.528 -122.323,-5.857 -246.676,54.096 -86.553,41.731 -166.863,32.344 -195.296,-22.832 l -4.082,-7.921 -6.746,5.825 c -46.979,40.567 -124.982,19.292 -189.696,-51.744 -30.269,-33.219 -57.095,-60.005 -81.409,-80.978 m -243.677,35.49 23.29,-27.449 c 31.108,-36.662 61.664,-54.761 93.414,-55.321 50.042,-0.886 109.26,40.302 198.007,137.713 67.27,73.852 149.202,96.884 202.613,58.168 5.161,8.218 11.395,15.426 18.56,21.608 41.537,35.828 114.363,37.093 191.121,0.085 118.703,-57.229 189.016,-73.322 235.105,-53.813 29.241,12.378 50.832,40.572 65.995,86.197 l 11.352,34.163 2.314,-35.926 c 0.069,-1.138 1.71,-28.327 -5.536,-64.815 -6.707,-33.796 -22.67,-82.162 -60.607,-120.664 -26.454,-26.843 -60.256,-45.68 -100.471,-55.988 -47.787,-12.251 -112.849,-15.536 -174.047,-8.786 -66.179,7.296 -120.926,25.65 -155.507,51.966 -22.25,-37.322 -66.189,-74.795 -124.86,-106.275 -54.248,-29.115 -115.838,-50.362 -164.744,-56.837 -94.828,-12.565 -156.408,32.223 -191.371,72.011 -37.596,42.783 -52.732,87.876 -53.357,89.776 z"
+ id="path748"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1041.9775,0,0,-1041.9775,1161.687,5231.604)"
+ spreadMethod="pad"
+ id="whatevs-1">
+ <stop
+ style="stop-opacity:1;stop-color:#cccccc"
+ offset="0"
+ id="stop752" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="1"
+ id="stop756" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath860">
+ <path
+ d="m 3217.535,2532.398 c -55.906,37.49 -84.611,71.163 -93.965,107.673 -6.549,25.579 -3.046,52.799 10.729,82.485 -12.371,-11.945 -26.763,-27.909 -39.52,-47.399 -17.471,-26.688 -28.504,-54.691 -32.802,-83.237 -5.36,-35.609 -0.191,-72.302 15.359,-109.072 35.383,-83.707 141.955,-212.642 235.125,-232.507 l 8.774,-1.868 -3.831,-8.107 c -40.703,-86.133 -2.786,-249.053 42.315,-327.944 19.55,-34.202 45.182,-60.327 76.181,-77.656 52.982,-29.619 111.602,-28 148.877,-22.365 -31.907,7.053 -55.635,20.762 -71.988,41.45 -34.647,43.85 -38.533,117.783 -13.401,255.199 17.496,95.648 -13.207,171.491 -74.673,184.432 l -8.82,1.86 3.871,8.139 c 26.98,56.725 -14.709,127.125 -101.381,171.208 -40.533,20.621 -73.864,39.614 -100.85,57.709 m -30.752,247.276 -20.535,-30.088 c -27.429,-40.19 -36.884,-74.856 -28.914,-105.984 12.565,-49.067 68.637,-95.794 187.491,-156.253 90.105,-45.826 134.56,-119.584 111.116,-182.084 9.405,-2.829 18.11,-6.984 26.063,-12.314 46.1,-30.909 66.872,-101.636 51.359,-186.457 -23.988,-131.175 -20.83,-204.099 10.57,-243.836 19.92,-25.204 53.224,-38.706 101.809,-41.26 l 36.38,-1.911 -34.434,-11.894 c -1.091,-0.379 -27.18,-9.273 -64.726,-11.99 -34.773,-2.531 -86.248,0.073 -133.992,26.764 -33.289,18.601 -60.736,46.533 -81.582,83.003 -24.781,43.339 -45.44,105.943 -55.277,167.464 -10.629,66.533 -7.41,124.876 8.992,165.672 -42.39,11.701 -90.738,44.514 -137.196,93.316 -42.964,45.119 -80.217,99.509 -99.656,145.493 -37.7,89.151 -10.517,161.257 18.918,206.044 31.658,48.161 71.595,75.026 73.28,76.151 z"
+ id="path858"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(616.29688,0,0,-616.29688,3045.8252,2287.2598)"
+ spreadMethod="pad"
+ id="linearGradient868">
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0"
+ id="stop862" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0.10691959"
+ id="stop864" />
+ <stop
+ style="stop-opacity:1;stop-color:#231f20"
+ offset="1"
+ id="stop866" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient758"
+ id="linearGradient12339-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(38.597503,0,0,38.597503,12.794587,52.903821)"
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ spreadMethod="pad" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath836">
+ <path
+ d="m 3287.719,2298.145 c -59.434,-102.862 -115.35,-157.371 -178.537,-178.134 -44.267,-14.548 -92.606,-11.588 -146.502,9.167 22.492,-20.371 52.302,-43.835 88.116,-64.003 49.051,-27.612 99.663,-43.747 150.431,-47.953 63.332,-5.243 127.341,8.172 190.252,39.886 143.218,72.167 357.711,275.011 381.711,441.402 l 2.26,15.669 14.73,-5.792 c 156.455,-61.525 438.868,24.431 572.474,113.136 57.917,38.451 100.897,86.663 127.765,143.287 45.914,96.784 36.16,199.816 21.852,264.786 -8.662,-57.009 -30.003,-100.412 -64.513,-131.645 -73.131,-66.17 -202.866,-81.714 -447.792,-53.649 -170.478,19.541 -300.407,-43.45 -315.954,-153.208 l -2.232,-15.757 -14.795,5.861 c -103.059,40.827 -222.109,-40.871 -289.527,-198.68 -31.534,-73.801 -61.053,-134.725 -89.739,-184.373 m -431.794,-83.271 55.395,-32.62 c 73.995,-43.561 136.159,-56.13 190.032,-38.429 84.915,27.904 160.591,132.138 253.05,348.544 70.081,164.064 194.728,251.027 307.542,217.106 3.876,16.887 10.158,32.706 18.611,47.332 49.005,84.824 171.089,129.73 322.27,112.406 233.803,-26.795 361.834,-12.641 428.108,47.326 42.046,38.045 61.898,98.28 60.668,184.132 l -0.921,64.283 25.005,-59.233 c 0.788,-1.879 19.521,-46.767 28.734,-112.562 8.542,-60.93 10.025,-151.872 -31.356,-239.096 -28.832,-60.802 -74.777,-112.418 -136.544,-153.422 -73.391,-48.735 -181.194,-92.495 -288.363,-117.053 -115.904,-26.552 -219.014,-27.759 -292.783,-3.682 -15.61,-76.019 -67.7,-165.02 -148.157,-252.569 -74.39,-80.964 -165.777,-152.97 -244.458,-192.617 -152.537,-76.88 -282.702,-37.516 -365.037,9.053 -88.526,50.066 -140.539,117.226 -142.714,120.061 z"
+ id="path834"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(56.469845,0,0,56.469845,28.865443,46.818235)"
+ spreadMethod="pad"
+ id="linearGradient844">
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0"
+ id="stop838" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0.10691959"
+ id="stop840" />
+ <stop
+ style="stop-opacity:1;stop-color:#231f20"
+ offset="1"
+ id="stop842" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1992">
+ <path
+ d="m 3311.591,5872.595 c -82.332,17.698 -131.288,43.547 -159.056,81.656 -19.451,26.7 -27.979,59.953 -25.715,100.834 -8.851,-19.611 -18.186,-44.832 -23.99,-73.387 -7.947,-39.1 -7.809,-76.762 0.406,-111.922 10.258,-43.87 33.247,-84.133 68.338,-119.667 79.877,-80.906 263.431,-181.44 380.912,-161.392 l 11.063,1.89 -0.701,-11.206 c -7.436,-118.943 112.048,-290.754 200.99,-361.568 38.553,-30.704 80.441,-49.203 124.49,-54.996 75.289,-9.895 142.674,19.121 183.391,42.925 -40.35,-6.577 -74.274,-1.626 -102.86,14.855 -60.566,34.923 -99.307,119.057 -133.706,290.409 -23.942,119.266 -94.735,193.201 -172.166,179.791 l -11.115,-1.925 0.732,11.256 c 5.101,78.417 -75.94,140.943 -197.081,152.06 -56.659,5.205 -104.189,11.846 -143.932,20.387 m -150.209,273.174 -9.936,-44.477 c -13.274,-59.407 -8.221,-104.083 15.453,-136.572 37.312,-51.21 124.118,-79.564 290.246,-94.813 125.942,-11.551 211.755,-76.704 213.439,-160.199 12.238,1.06 24.277,0.268 35.99,-2.249 67.891,-14.588 124.771,-87.169 146.004,-192.938 32.84,-163.568 70.271,-246.86 125.156,-278.51 34.829,-20.079 79.784,-20.356 137.433,-0.831 l 43.169,14.619 -34.514,-29.765 c -1.097,-0.94 -27.299,-23.36 -69.677,-43.899 -39.251,-19.03 -100.281,-39.834 -168.131,-30.92 -47.303,6.223 -92.131,25.974 -133.249,58.713 -48.855,38.906 -101.847,102.103 -141.753,169.055 -43.16,72.403 -66.426,141.703 -66.252,196.714 -54.678,-6.022 -126.065,9.736 -202.651,44.952 -70.82,32.556 -139.297,78.527 -183.178,122.975 -85.089,86.166 -86.874,182.55 -73.389,248.234 14.5,70.629 48.48,120.346 49.921,122.426 z"
+ id="path1990"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1079.04,0,0,-1079.04,3079.2959,5644.4287)"
+ spreadMethod="pad"
+ id="linearGradient2000">
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0"
+ id="stop1994" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0.10691959"
+ id="stop1996" />
+ <stop
+ style="stop-opacity:1;stop-color:#231f20"
+ offset="1"
+ id="stop1998" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12837"
+ id="linearGradient12839"
+ x1="24.9897"
+ y1="43.494854"
+ x2="112.07853"
+ y2="49.820049"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#whatevs-1"
+ id="linearGradient12893"
+ x1="17.733486"
+ y1="48.622395"
+ x2="23.333635"
+ y2="48.622395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.26701219,0,0,0.64081556,13.000775,16.966749)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="179.49327"
+ inkscape:cy="935.91734"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="991"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata11442">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect11477"
+ width="146.65475"
+ height="61.988094"
+ x="3.0238097"
+ y="23.723215" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient12839);fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect11473"
+ width="105"
+ height="11.8"
+ x="17.764881"
+ y="42.244045"
+ inkscape:export-xdpi="253.46324"
+ inkscape:export-ydpi="253.46324" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient12893);fill-opacity:1;stroke:#f1c6f1;stroke-width:0.01034123;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect12885"
+ width="1.4886327"
+ height="11.686779"
+ x="17.73917"
+ y="42.281345" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path810-9"
+ style="opacity:0.117;fill:url(#linearGradient12339-5);stroke:none;stroke-width:0.03704255"
+ d="m 12.794586,52.963496 0.862722,1.016781 c 4.098478,4.603131 8.523732,-0.582855 10.794976,-3.05201 2.491852,-2.735667 5.526822,-3.58883 7.505302,-2.154691 0.191176,-0.304416 0.4221,-0.571418 0.68751,-0.800415 1.538636,-1.327161 4.236297,-1.37402 7.079609,-0.0031 4.397063,2.119907 7.001633,2.716034 8.708888,1.993371 1.083163,-0.458514 1.88295,-1.502891 2.444624,-3.192957 l 0.420506,-1.265484 0.08571,1.33079 c 0.0024,0.04215 0.06334,1.049304 -0.205067,2.400912 -0.248443,1.25189 -0.839753,3.04349 -2.245037,4.469703 -0.979923,0.994333 -2.232035,1.692104 -3.721699,2.073938 -1.770157,0.453809 -4.180218,0.575493 -6.447148,0.325456 -2.45144,-0.270262 -4.479408,-0.950142 -5.760377,-1.924954 -0.824196,1.382503 -2.451808,2.770599 -4.625132,3.936698 -2.009484,1.078493 -4.290935,1.865536 -6.102538,2.105387 -3.51267,0.46544 -5.793751,-1.193623 -7.08887,-2.667471 -1.392651,-1.584792 -1.953327,-3.255151 -1.976478,-3.325532 z"
+ sodipodi:nodetypes="cccccccccccccccccccc" />
+ <g
+ id="g966"
+ transform="matrix(0.02991036,0,0,-0.02991036,-6.3821215,124.57045)"
+ style="opacity:0.32000002">
+ <g
+ id="g964">
+ <path
+ inkscape:connector-curvature="0"
+ id="path962"
+ style="fill:url(#linearGradient868);stroke:none"
+ d="m 3186.783,2779.674 -20.535,-30.088 c -27.429,-40.19 -36.884,-74.856 -28.914,-105.984 12.565,-49.067 68.637,-95.794 187.491,-156.253 90.105,-45.826 134.56,-119.584 111.116,-182.084 9.405,-2.829 18.11,-6.984 26.063,-12.314 46.1,-30.909 66.872,-101.636 51.359,-186.457 -23.988,-131.175 -20.83,-204.099 10.57,-243.836 19.92,-25.204 53.224,-38.706 101.809,-41.26 l 36.38,-1.911 -34.434,-11.894 c -1.091,-0.379 -27.18,-9.273 -64.726,-11.99 -34.773,-2.531 -86.248,0.073 -133.992,26.764 -33.289,18.601 -60.736,46.533 -81.582,83.003 -24.781,43.339 -45.44,105.943 -55.277,167.464 -10.629,66.533 -7.41,124.876 8.992,165.672 -42.39,11.701 -90.738,44.514 -137.196,93.316 -42.964,45.119 -80.217,99.509 -99.656,145.493 -37.7,89.151 -10.517,161.257 18.918,206.044 31.658,48.161 71.595,75.026 73.28,76.151 z"
+ sodipodi:nodetypes="ccccccccccccccccccccc" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path942"
+ style="opacity:0.106;fill:url(#linearGradient844);stroke:none;stroke-width:0.03334784"
+ d="m 28.865456,58.931351 1.847304,1.087807 c 2.467573,1.452665 4.540608,1.871814 6.337156,1.281524 2.831732,-0.930538 5.355363,-4.406517 8.438671,-11.62319 2.33705,-5.47118 6.493758,-8.371208 10.255862,-7.240016 0.129256,-0.563145 0.338747,-1.090674 0.620636,-1.57842 1.634211,-2.828697 5.705449,-4.326215 10.747009,-3.748497 7.796825,0.893555 12.066382,0.42155 14.276477,-1.57822 1.402143,-1.268718 2.064164,-3.277426 2.023146,-6.140404 l -0.03071,-2.1437 0.833863,1.975293 c 0.02628,0.06266 0.650983,1.559578 0.958217,3.7537 0.284857,2.031883 0.334312,5.064603 -1.045655,7.973335 -0.961485,2.027615 -2.493652,3.748897 -4.553448,5.116292 -2.447431,1.625207 -6.042428,3.084508 -9.616283,3.903465 -3.865148,0.885452 -7.303644,0.925702 -9.76368,0.122786 -0.52056,2.53507 -2.257649,5.503061 -4.940716,8.422631 C 52.772559,61.215712 49.725,63.616956 47.101158,64.939098 42.01437,67.50288 37.673648,66.190176 34.927954,64.6372 31.975803,62.967607 30.241282,60.727966 30.16875,60.633425 Z"
+ sodipodi:nodetypes="ccccccccccccccccccccc" />
+ <g
+ id="g2084"
+ transform="matrix(0.0224278,0,0,-0.0224278,32.577361,174.7361)"
+ style="opacity:0.27">
+ <g
+ id="g2082"
+ style="">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path2080"
+ style="fill:url(#linearGradient2000);stroke:none"
+ d="m 3161.382,6145.769 -9.936,-44.477 c -13.274,-59.407 -8.221,-104.083 15.453,-136.572 37.312,-51.21 124.118,-79.564 290.246,-94.813 125.942,-11.551 211.755,-76.704 213.439,-160.199 12.238,1.06 24.277,0.268 35.99,-2.249 67.891,-14.588 124.771,-87.169 146.004,-192.938 32.84,-163.568 70.271,-246.86 125.156,-278.51 34.829,-20.079 79.784,-20.356 137.433,-0.831 l 43.169,14.619 -34.514,-29.765 c -1.097,-0.94 -27.299,-23.36 -69.677,-43.899 -39.251,-19.03 -100.281,-39.834 -168.131,-30.92 -47.303,6.223 -92.131,25.974 -133.249,58.713 -48.855,38.906 -101.847,102.103 -141.753,169.055 -43.16,72.403 -66.426,141.703 -66.252,196.714 -54.678,-6.022 -126.065,9.736 -202.651,44.952 -70.82,32.556 -139.297,78.527 -183.178,122.975 -85.089,86.166 -86.874,182.55 -73.389,248.234 14.5,70.629 48.48,120.346 49.921,122.426 z" />
+ </g>
+ </g>
+ <path
+ style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4.1806233,53.981494 V 115.96943 H 150.83575 V 53.981494 Z"
+ id="rect11477-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 5.2496761,-19.743869 V 42.244072 H 151.90481 v -61.987941 z"
+ id="rect11477-3-7"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg11445"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bg2.svg">
+ <defs
+ id="defs11439">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient877">
+ <stop
+ style="stop-color:#4444cc;stop-opacity:1"
+ offset="0"
+ id="stop873" />
+ <stop
+ style="stop-color:#3535c2;stop-opacity:1"
+ offset="1"
+ id="stop875" />
+ </linearGradient>
+ <linearGradient
+ id="blueish-6-7-5"
+ inkscape:collect="always">
+ <stop
+ id="stop858"
+ offset="0"
+ style="stop-color:#3333aa;stop-opacity:1" />
+ <stop
+ id="stop860"
+ offset="1"
+ style="stop-color:#4444cc;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient758"
+ spreadMethod="pad"
+ gradientTransform="matrix(1041.9775,0,0,-1041.9775,1161.687,5231.604)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop12314"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ffffff" />
+ <stop
+ id="stop12316"
+ offset="0.10691959"
+ style="stop-opacity:1;stop-color:#ffffff" />
+ <stop
+ id="stop12318"
+ offset="1"
+ style="stop-opacity:1;stop-color:#231f20" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath750">
+ <path
+ d="m 1405.364,5194.503 c -50.371,-43.444 -89.981,-61.977 -127.217,-61.319 -26.092,0.466 -51.105,10.931 -75.785,31.831 8.139,-14.917 19.583,-32.813 34.809,-50.074 20.852,-23.635 44.648,-41.487 70.716,-53.059 32.528,-14.439 68.85,-19.132 107.953,-13.948 89.028,11.79 239.813,79.55 283.148,163.123 l 4.079,7.872 6.725,-5.78 c 71.402,-61.345 236.579,-67.907 323.568,-45.6 37.707,9.668 69.318,27.248 93.953,52.243 42.102,42.724 55.918,99.005 60.318,135.999 -15.08,-28.557 -34.359,-47.574 -58.362,-57.734 -50.856,-21.528 -122.323,-5.857 -246.676,54.096 -86.553,41.731 -166.863,32.344 -195.296,-22.832 l -4.082,-7.921 -6.746,5.825 c -46.979,40.567 -124.982,19.292 -189.696,-51.744 -30.269,-33.219 -57.095,-60.005 -81.409,-80.978 m -243.677,35.49 23.29,-27.449 c 31.108,-36.662 61.664,-54.761 93.414,-55.321 50.042,-0.886 109.26,40.302 198.007,137.713 67.27,73.852 149.202,96.884 202.613,58.168 5.161,8.218 11.395,15.426 18.56,21.608 41.537,35.828 114.363,37.093 191.121,0.085 118.703,-57.229 189.016,-73.322 235.105,-53.813 29.241,12.378 50.832,40.572 65.995,86.197 l 11.352,34.163 2.314,-35.926 c 0.069,-1.138 1.71,-28.327 -5.536,-64.815 -6.707,-33.796 -22.67,-82.162 -60.607,-120.664 -26.454,-26.843 -60.256,-45.68 -100.471,-55.988 -47.787,-12.251 -112.849,-15.536 -174.047,-8.786 -66.179,7.296 -120.926,25.65 -155.507,51.966 -22.25,-37.322 -66.189,-74.795 -124.86,-106.275 -54.248,-29.115 -115.838,-50.362 -164.744,-56.837 -94.828,-12.565 -156.408,32.223 -191.371,72.011 -37.596,42.783 -52.732,87.876 -53.357,89.776 z"
+ id="path748"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1041.9775,0,0,-1041.9775,1161.687,5231.604)"
+ spreadMethod="pad"
+ id="whatevs-1">
+ <stop
+ style="stop-opacity:1;stop-color:#cccccc"
+ offset="0"
+ id="stop752" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="1"
+ id="stop756" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath860">
+ <path
+ d="m 3217.535,2532.398 c -55.906,37.49 -84.611,71.163 -93.965,107.673 -6.549,25.579 -3.046,52.799 10.729,82.485 -12.371,-11.945 -26.763,-27.909 -39.52,-47.399 -17.471,-26.688 -28.504,-54.691 -32.802,-83.237 -5.36,-35.609 -0.191,-72.302 15.359,-109.072 35.383,-83.707 141.955,-212.642 235.125,-232.507 l 8.774,-1.868 -3.831,-8.107 c -40.703,-86.133 -2.786,-249.053 42.315,-327.944 19.55,-34.202 45.182,-60.327 76.181,-77.656 52.982,-29.619 111.602,-28 148.877,-22.365 -31.907,7.053 -55.635,20.762 -71.988,41.45 -34.647,43.85 -38.533,117.783 -13.401,255.199 17.496,95.648 -13.207,171.491 -74.673,184.432 l -8.82,1.86 3.871,8.139 c 26.98,56.725 -14.709,127.125 -101.381,171.208 -40.533,20.621 -73.864,39.614 -100.85,57.709 m -30.752,247.276 -20.535,-30.088 c -27.429,-40.19 -36.884,-74.856 -28.914,-105.984 12.565,-49.067 68.637,-95.794 187.491,-156.253 90.105,-45.826 134.56,-119.584 111.116,-182.084 9.405,-2.829 18.11,-6.984 26.063,-12.314 46.1,-30.909 66.872,-101.636 51.359,-186.457 -23.988,-131.175 -20.83,-204.099 10.57,-243.836 19.92,-25.204 53.224,-38.706 101.809,-41.26 l 36.38,-1.911 -34.434,-11.894 c -1.091,-0.379 -27.18,-9.273 -64.726,-11.99 -34.773,-2.531 -86.248,0.073 -133.992,26.764 -33.289,18.601 -60.736,46.533 -81.582,83.003 -24.781,43.339 -45.44,105.943 -55.277,167.464 -10.629,66.533 -7.41,124.876 8.992,165.672 -42.39,11.701 -90.738,44.514 -137.196,93.316 -42.964,45.119 -80.217,99.509 -99.656,145.493 -37.7,89.151 -10.517,161.257 18.918,206.044 31.658,48.161 71.595,75.026 73.28,76.151 z"
+ id="path858"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(616.29688,0,0,-616.29688,3045.8252,2287.2598)"
+ spreadMethod="pad"
+ id="linearGradient868">
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0"
+ id="stop862" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0.10691959"
+ id="stop864" />
+ <stop
+ style="stop-opacity:1;stop-color:#231f20"
+ offset="1"
+ id="stop866" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#blueish-6-7-5"
+ id="linearGradient12339-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(38.597503,0,0,38.597503,12.794587,52.903821)"
+ x1="0.30357563"
+ y1="-0.051412005"
+ x2="1"
+ y2="0"
+ spreadMethod="pad" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath836">
+ <path
+ d="m 3287.719,2298.145 c -59.434,-102.862 -115.35,-157.371 -178.537,-178.134 -44.267,-14.548 -92.606,-11.588 -146.502,9.167 22.492,-20.371 52.302,-43.835 88.116,-64.003 49.051,-27.612 99.663,-43.747 150.431,-47.953 63.332,-5.243 127.341,8.172 190.252,39.886 143.218,72.167 357.711,275.011 381.711,441.402 l 2.26,15.669 14.73,-5.792 c 156.455,-61.525 438.868,24.431 572.474,113.136 57.917,38.451 100.897,86.663 127.765,143.287 45.914,96.784 36.16,199.816 21.852,264.786 -8.662,-57.009 -30.003,-100.412 -64.513,-131.645 -73.131,-66.17 -202.866,-81.714 -447.792,-53.649 -170.478,19.541 -300.407,-43.45 -315.954,-153.208 l -2.232,-15.757 -14.795,5.861 c -103.059,40.827 -222.109,-40.871 -289.527,-198.68 -31.534,-73.801 -61.053,-134.725 -89.739,-184.373 m -431.794,-83.271 55.395,-32.62 c 73.995,-43.561 136.159,-56.13 190.032,-38.429 84.915,27.904 160.591,132.138 253.05,348.544 70.081,164.064 194.728,251.027 307.542,217.106 3.876,16.887 10.158,32.706 18.611,47.332 49.005,84.824 171.089,129.73 322.27,112.406 233.803,-26.795 361.834,-12.641 428.108,47.326 42.046,38.045 61.898,98.28 60.668,184.132 l -0.921,64.283 25.005,-59.233 c 0.788,-1.879 19.521,-46.767 28.734,-112.562 8.542,-60.93 10.025,-151.872 -31.356,-239.096 -28.832,-60.802 -74.777,-112.418 -136.544,-153.422 -73.391,-48.735 -181.194,-92.495 -288.363,-117.053 -115.904,-26.552 -219.014,-27.759 -292.783,-3.682 -15.61,-76.019 -67.7,-165.02 -148.157,-252.569 -74.39,-80.964 -165.777,-152.97 -244.458,-192.617 -152.537,-76.88 -282.702,-37.516 -365.037,9.053 -88.526,50.066 -140.539,117.226 -142.714,120.061 z"
+ id="path834"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(12.41424,0,0,12.41424,43.304872,52.53415)"
+ spreadMethod="pad"
+ id="linearGradient844">
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0"
+ id="stop838" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0.10691959"
+ id="stop840" />
+ <stop
+ style="stop-opacity:1;stop-color:#231f20"
+ offset="1"
+ id="stop842" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1992">
+ <path
+ d="m 3311.591,5872.595 c -82.332,17.698 -131.288,43.547 -159.056,81.656 -19.451,26.7 -27.979,59.953 -25.715,100.834 -8.851,-19.611 -18.186,-44.832 -23.99,-73.387 -7.947,-39.1 -7.809,-76.762 0.406,-111.922 10.258,-43.87 33.247,-84.133 68.338,-119.667 79.877,-80.906 263.431,-181.44 380.912,-161.392 l 11.063,1.89 -0.701,-11.206 c -7.436,-118.943 112.048,-290.754 200.99,-361.568 38.553,-30.704 80.441,-49.203 124.49,-54.996 75.289,-9.895 142.674,19.121 183.391,42.925 -40.35,-6.577 -74.274,-1.626 -102.86,14.855 -60.566,34.923 -99.307,119.057 -133.706,290.409 -23.942,119.266 -94.735,193.201 -172.166,179.791 l -11.115,-1.925 0.732,11.256 c 5.101,78.417 -75.94,140.943 -197.081,152.06 -56.659,5.205 -104.189,11.846 -143.932,20.387 m -150.209,273.174 -9.936,-44.477 c -13.274,-59.407 -8.221,-104.083 15.453,-136.572 37.312,-51.21 124.118,-79.564 290.246,-94.813 125.942,-11.551 211.755,-76.704 213.439,-160.199 12.238,1.06 24.277,0.268 35.99,-2.249 67.891,-14.588 124.771,-87.169 146.004,-192.938 32.84,-163.568 70.271,-246.86 125.156,-278.51 34.829,-20.079 79.784,-20.356 137.433,-0.831 l 43.169,14.619 -34.514,-29.765 c -1.097,-0.94 -27.299,-23.36 -69.677,-43.899 -39.251,-19.03 -100.281,-39.834 -168.131,-30.92 -47.303,6.223 -92.131,25.974 -133.249,58.713 -48.855,38.906 -101.847,102.103 -141.753,169.055 -43.16,72.403 -66.426,141.703 -66.252,196.714 -54.678,-6.022 -126.065,9.736 -202.651,44.952 -70.82,32.556 -139.297,78.527 -183.178,122.975 -85.089,86.166 -86.874,182.55 -73.389,248.234 14.5,70.629 48.48,120.346 49.921,122.426 z"
+ id="path1990"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1079.04,0,0,-1079.04,3079.2959,5644.4287)"
+ spreadMethod="pad"
+ id="linearGradient2000">
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0"
+ id="stop1994" />
+ <stop
+ style="stop-opacity:1;stop-color:#ffffff"
+ offset="0.10691959"
+ id="stop1996" />
+ <stop
+ style="stop-opacity:1;stop-color:#231f20"
+ offset="1"
+ id="stop1998" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient877"
+ id="linearGradient12839"
+ x1="24.9897"
+ y1="43.494854"
+ x2="112.07853"
+ y2="49.820049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.47609494,0,0,0.33813298,9.2996261,35.777456)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#blueish-6-7-5"
+ id="linearGradient12893"
+ x1="17.733486"
+ y1="48.622395"
+ x2="23.333635"
+ y2="48.622395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.26778116,0,0,0.21899812,13.079481,41.415524)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.959798"
+ inkscape:cx="184.87769"
+ inkscape:cy="915.77886"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="991"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata11442">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect11477"
+ width="146.65475"
+ height="61.988094"
+ x="3.0238097"
+ y="23.723215" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient12839);fill-opacity:1.0;stroke:#9e9e9e;stroke-width:0.01003068;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect11473"
+ width="49.989971"
+ height="3.9899693"
+ x="17.757397"
+ y="50.061562"
+ inkscape:export-xdpi="254"
+ inkscape:export-ydpi="254" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient12893);fill-opacity:1;stroke:none;stroke-width:0.00605411;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect12885"
+ width="1.4929198"
+ height="3.9939458"
+ x="17.831524"
+ y="50.066765" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path810-9"
+ style="opacity:0.117;fill:url(#linearGradient12339-5);stroke:none;stroke-width:0.03704255;fill-opacity:1"
+ d="m 12.794586,52.963496 0.862722,1.016781 c 4.098478,4.603131 8.523732,-0.582855 10.794976,-3.05201 2.491852,-2.735667 5.526822,-3.58883 7.505302,-2.154691 0.191176,-0.304416 0.4221,-0.571418 0.68751,-0.800415 1.538636,-1.327161 4.236297,-1.37402 7.079609,-0.0031 4.397063,2.119907 7.001633,2.716034 8.708888,1.993371 1.083163,-0.458514 1.88295,-1.502891 2.444624,-3.192957 l 0.420506,-1.265484 0.08571,1.33079 c 0.0024,0.04215 0.06334,1.049304 -0.205067,2.400912 -0.248443,1.25189 -0.839753,3.04349 -2.245037,4.469703 -0.979923,0.994333 -2.232035,1.692104 -3.721699,2.073938 -1.770157,0.453809 -4.180218,0.575493 -6.447148,0.325456 -2.45144,-0.270262 -4.479408,-0.950142 -5.760377,-1.924954 -0.824196,1.382503 -2.451808,2.770599 -4.625132,3.936698 -2.009484,1.078493 -4.290935,1.865536 -6.102538,2.105387 -3.51267,0.46544 -5.793751,-1.193623 -7.08887,-2.667471 -1.392651,-1.584792 -1.953327,-3.255151 -1.976478,-3.325532 z"
+ sodipodi:nodetypes="cccccccccccccccccccc" />
+ <g
+ id="g966"
+ transform="matrix(0.02991036,0,0,-0.02991036,-31.177093,124.43682)"
+ style="opacity:0.056">
+ <g
+ id="g964">
+ <path
+ inkscape:connector-curvature="0"
+ id="path962"
+ style="fill:url(#linearGradient868);stroke:none"
+ d="m 3186.783,2779.674 -20.535,-30.088 c -27.429,-40.19 -36.884,-74.856 -28.914,-105.984 12.565,-49.067 68.637,-95.794 187.491,-156.253 90.105,-45.826 134.56,-119.584 111.116,-182.084 9.405,-2.829 18.11,-6.984 26.063,-12.314 46.1,-30.909 66.872,-101.636 51.359,-186.457 -23.988,-131.175 -20.83,-204.099 10.57,-243.836 19.92,-25.204 53.224,-38.706 101.809,-41.26 l 36.38,-1.911 -34.434,-11.894 c -1.091,-0.379 -27.18,-9.273 -64.726,-11.99 -34.773,-2.531 -86.248,0.073 -133.992,26.764 -33.289,18.601 -60.736,46.533 -81.582,83.003 -24.781,43.339 -45.44,105.943 -55.277,167.464 -10.629,66.533 -7.41,124.876 8.992,165.672 -42.39,11.701 -90.738,44.514 -137.196,93.316 -42.964,45.119 -80.217,99.509 -99.656,145.493 -37.7,89.151 -10.517,161.257 18.918,206.044 31.658,48.161 71.595,75.026 73.28,76.151 z"
+ sodipodi:nodetypes="ccccccccccccccccccccc" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path942"
+ style="opacity:0.106;fill:url(#linearGradient844);stroke:none;stroke-width:0.00733114"
+ d="m 43.304875,55.197077 0.406108,0.239142 c 0.542468,0.319352 0.998201,0.411497 1.393151,0.281729 0.622523,-0.204568 1.177314,-0.968722 1.855144,-2.555224 0.513773,-1.202775 1.427577,-1.840313 2.254632,-1.591634 0.02841,-0.1238 0.07447,-0.239771 0.136439,-0.346996 0.359263,-0.621857 1.254277,-0.951069 2.362606,-0.824064 1.714042,0.196437 2.652654,0.09267 3.138518,-0.346954 0.308245,-0.278912 0.453782,-0.720504 0.444765,-1.349897 l -0.0067,-0.471267 0.183314,0.434245 c 0.0058,0.01377 0.143111,0.342856 0.210653,0.825208 0.06262,0.446686 0.07349,1.113394 -0.229875,1.752845 -0.211372,0.445747 -0.5482,0.824152 -1.001023,1.124758 -0.538039,0.357283 -1.328358,0.678093 -2.114028,0.858131 -0.849708,0.194656 -1.605621,0.203505 -2.146432,0.02699 -0.114438,0.557305 -0.496317,1.209784 -1.086159,1.851617 -0.545363,0.593558 -1.215333,1.121444 -1.792155,1.412102 -1.118271,0.563617 -2.072529,0.275035 -2.676138,-0.06637 -0.648995,-0.36704 -1.03031,-0.859399 -1.046255,-0.880183 z"
+ sodipodi:nodetypes="ccccccccccccccccccccc" />
+ <g
+ id="g2084"
+ transform="matrix(0.0224278,0,0,-0.0224278,-48.385178,174.7361)"
+ style="opacity:0.083">
+ <g
+ id="g2082"
+ style="">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path2080"
+ style="fill:url(#linearGradient2000);stroke:none"
+ d="m 3161.382,6145.769 -9.936,-44.477 c -13.274,-59.407 -8.221,-104.083 15.453,-136.572 37.312,-51.21 124.118,-79.564 290.246,-94.813 125.942,-11.551 211.755,-76.704 213.439,-160.199 12.238,1.06 24.277,0.268 35.99,-2.249 67.891,-14.588 124.771,-87.169 146.004,-192.938 32.84,-163.568 70.271,-246.86 125.156,-278.51 34.829,-20.079 79.784,-20.356 137.433,-0.831 l 43.169,14.619 -34.514,-29.765 c -1.097,-0.94 -27.299,-23.36 -69.677,-43.899 -39.251,-19.03 -100.281,-39.834 -168.131,-30.92 -47.303,6.223 -92.131,25.974 -133.249,58.713 -48.855,38.906 -101.847,102.103 -141.753,169.055 -43.16,72.403 -66.426,141.703 -66.252,196.714 -54.678,-6.022 -126.065,9.736 -202.651,44.952 -70.82,32.556 -139.297,78.527 -183.178,122.975 -85.089,86.166 -86.874,182.55 -73.389,248.234 14.5,70.629 48.48,120.346 49.921,122.426 z" />
+ </g>
+ </g>
+ <path
+ style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4.1806233,53.981494 V 115.96943 H 150.83575 V 53.981494 Z"
+ id="rect11477-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#9e9e9e;stroke-width:0.025;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 5.2496761,-12.052049 V 49.935892 H 151.90481 v -61.987941 z"
+ id="rect11477-3-7"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<configuration>\r
+ <paths>\r
+ <media-path>media/</media-path>\r
+ <log-path>log/</log-path>\r
+ <data-path>data/</data-path>\r
+ <template-path>template/</template-path>\r
+ <thumbnail-path>thumbnail/</thumbnail-path>\r
+ <font-path>font/</font-path>\r
+ </paths>\r
+ <lock-clear-phrase>secret</lock-clear-phrase>\r
+ <channels>\r
+ <channel>\r
+ <video-mode>720p5994</video-mode>\r
+ <channel-layout>stereo</channel-layout>\r
+ <consumers>\r
+ <!-- <screen>\r
+ <device>1</device>\r
+ <windowed>true</windowed>\r
+ </screen> -->\r
+ <ffmpeg>\r
+ <device>1</device>\r
+ <path>unix:///tmp/caspar.sock</path>\r
+ <!-- <path>udp://localhost:5251/</path> -->\r
+ <args>-c:v rawvideo -vf format=pix_fmts=bgra -f nut -listen 1</args>\r
+ </ffmpeg>\r
+ <system-audio></system-audio>\r
+ </consumers>\r
+ </channel>\r
+ </channels>\r
+ <controllers>\r
+ <tcp>\r
+ <port>5250</port>\r
+ <protocol>AMCP</protocol>\r
+ </tcp>\r
+ <tcp>\r
+ <port>3250</port>\r
+ <protocol>LOG</protocol>\r
+ </tcp>\r
+ </controllers>\r
+</configuration>\r
+\r
+<!--\r
+<log-level> info [trace|debug|info|warning|error|fatal]</log-level>\r
+<log-categories> communication [calltrace|communication|calltrace,communication]</log-categories>\r
+<force-deinterlace> false [true|false]</force-deinterlace>\r
+<channel-grid> false [true|false]</channel-grid>\r
+<mixer>\r
+ <blend-modes> false [true|false]</blend-modes>\r
+ <mipmapping_default_on>false [true|false]</mipmapping_default_on>\r
+ <straight-alpha> false [true|false]</straight-alpha>\r
+</mixer>\r
+<accelerator>auto [cpu|gpu|auto]</accelerator>\r
+<template-hosts>\r
+ <template-host>\r
+ <video-mode />\r
+ <filename />\r
+ <width />\r
+ <height />\r
+ </template-host>\r
+</template-hosts>\r
+<flash>\r
+ <buffer-depth>auto [auto|1..]</buffer-depth>\r
+</flash>\r
+<html>\r
+ <remote-debugging-port>0 [0|1024-65535]</remote-debugging-port>\r
+</html>\r
+<thumbnails>\r
+ <generate-thumbnails>true [true|false]</generate-thumbnails>\r
+ <width>256</width>\r
+ <height>144</height>\r
+ <video-grid>2</video-grid>\r
+ <scan-interval-millis>5000</scan-interval-millis>\r
+ <generate-delay-millis>2000</generate-delay-millis>\r
+ <video-mode>720p2500</video-mode>\r
+ <mipmap>true</mipmap>\r
+</thumbnails>\r
+<channels>\r
+ <channel>\r
+ <video-mode>PAL [PAL|NTSC|576p2500|720p2398|720p2400|720p2500|720p5000|720p2997|720p5994|720p3000|720p6000|1080p2398|1080p2400|1080i5000|1080i5994|1080i6000|1080p2500|1080p2997|1080p3000|1080p5000|1080p5994|1080p6000|1556p2398|1556p2400|1556p2500|dci1080p2398|dci1080p2400|dci1080p2500|2160p2398|2160p2400|2160p2500|2160p2997|2160p3000|dci2160p2398|dci2160p2400|dci2160p2500] </video-mode>\r
+ <straight-alpha-output>false [true|false]</straight-alpha-output>\r
+ <channel-layout>stereo [mono|stereo|matrix|film|smpte|ebu_r123_8a|ebu_r123_8b|8ch|16ch]</channel-layout>\r
+ <consumers>\r
+ <decklink>\r
+ <device>[1..]</device>\r
+ <key-device>device + 1 [1..]</key-device>\r
+ <embedded-audio>false [true|false]</embedded-audio>\r
+ <channel-layout>stereo [mono|stereo|matrix|film|smpte|ebu_r123_8a|ebu_r123_8b|8ch|16ch]</channel-layout>\r
+ <latency>normal [normal|low|default]</latency>\r
+ <keyer>external [external|external_separate_device|internal|default]</keyer>\r
+ <key-only>false [true|false]</key-only>\r
+ <buffer-depth>3 [1..]</buffer-depth>\r
+ </decklink>\r
+ <bluefish>\r
+ <device>[1..]</device>\r
+ <embedded-audio>false [true|false]</embedded-audio>\r
+ <channel-layout>stereo [mono|stereo|matrix|film|smpte|ebu_r123_8a|ebu_r123_8b|8ch|16ch]</channel-layout>\r
+ <key-only>false [true|false]</key-only>\r
+ </bluefish>\r
+ <system-audio>\r
+ <channel-layout>stereo [mono|stereo|matrix]</channel-layout>\r
+ <latency>200 [0..]</latency>\r
+ </system-audio>\r
+ <screen>\r
+ <device>[0..]</device>\r
+ <aspect-ratio>default [default|4:3|16:9]</aspect-ratio>\r
+ <stretch>fill [none|fill|uniform|uniform_to_fill]</stretch>\r
+ <windowed>true [true|false]</windowed>\r
+ <key-only>false [true|false]</key-only>\r
+ <auto-deinterlace>true [true|false]</auto-deinterlace>\r
+ <vsync>false [true|false]</vsync>\r
+ <interactive>true [true|false]</interactive>\r
+ <borderless>false [true|false]</borderless>\r
+ </screen>\r
+ <newtek-ivga></newtek-ivga>\r
+ <ffmpeg>\r
+ <path>[file|url]</path>\r
+ <args>[most ffmpeg arguments related to filtering and output codecs]</args>\r
+ <separate-key>false [true|false]</separate-key>\r
+ <mono-streams>false [true|false]</mono-streams>\r
+ </ffmpeg>\r
+ <syncto>\r
+ <channel-id>1</channel-id>\r
+ </syncto>\r
+ </consumers>\r
+ </channel>\r
+</channels>\r
+<osc>\r
+ <default-port>6250</default-port>\r
+ <disable-send-to-amcp-clients>false [true|false]</disable-send-to-amcp-clients>\r
+ <predefined-clients>\r
+ <predefined-client>\r
+ <address>127.0.0.1</address>\r
+ <port>5253</port>\r
+ </predefined-client>\r
+ </predefined-clients>\r
+</osc>\r
+<audio>\r
+ <channel-layouts>\r
+ <channel-layout name="mono" type="mono" num-channels="1" channel-order="FC" />\r
+ <channel-layout name="stereo" type="stereo" num-channels="2" channel-order="FL FR" />\r
+ <channel-layout name="matrix" type="matrix" num-channels="2" channel-order="ML MR" />\r
+ <channel-layout name="film" type="5.1" num-channels="6" channel-order="FL FC FR BL BR LFE" />\r
+ <channel-layout name="smpte" type="5.1" num-channels="6" channel-order="FL FR FC LFE BL BR" />\r
+ <channel-layout name="ebu_r123_8a" type="5.1+downmix" num-channels="8" channel-order="DL DR FL FR FC LFE BL BR" />\r
+ <channel-layout name="ebu_r123_8b" type="5.1+downmix" num-channels="8" channel-order="FL FR FC LFE BL BR DL DR" />\r
+ <channel-layout name="8ch" type="8ch" num-channels="8" />\r
+ <channel-layout name="16ch" type="16ch" num-channels="16" />\r
+ </channel-layouts>\r
+ <mix-configs>\r
+ <mix-config from-type="mono" to-types="stereo, 5.1" mix="FL = FC | FR = FC" />\r
+ <mix-config from-type="mono" to-types="5.1+downmix" mix="FL = FC | FR = FC | DL = FC | DR = FC" />\r
+ <mix-config from-type="mono" to-types="matrix" mix="ML = FC | MR = FC" />\r
+ <mix-config from-type="stereo" to-types="mono" mix="FC < FL + FR" />\r
+ <mix-config from-type="stereo" to-types="matrix" mix="ML = FL | MR = FR" />\r
+ <mix-config from-type="stereo" to-types="5.1" mix="FL = FL | FR = FR" />\r
+ <mix-config from-type="stereo" to-types="5.1+downmix" mix="FL = FL | FR = FR | DL = FL | DR = FR" />\r
+ <mix-config from-type="5.1" to-types="mono" mix="FC < FL + FR + 0.707*FC + 0.707*BL + 0.707*BR" />\r
+ <mix-config from-type="5.1" to-types="stereo" mix="FL < FL + 0.707*FC + 0.707*BL | FR < FR + 0.707*FC + 0.707*BR" />\r
+ <mix-config from-type="5.1" to-types="5.1+downmix" mix="FL = FL | FR = FR | FC = FC | BL = BL | BR = BR | LFE = LFE | DL < FL + 0.707*FC + 0.707*BL | DR < FR + 0.707*FC + 0.707*BR" />\r
+ <mix-config from-type="5.1" to-types="matrix" mix="ML = 0.3204*FL + 0.293*FC + -0.293*BL + -0.293*BR | MR = 0.3204*FR + 0.293*FC + 0.293*BL + 0.293*BR" />\r
+ <mix-config from-type="5.1+stereomix" to-types="mono" mix="FC < DL + DR" />\r
+ <mix-config from-type="5.1+stereomix" to-types="stereo" mix="FL = DL | FR = DR" />\r
+ <mix-config from-type="5.1+stereomix" to-types="5.1" mix="FL = FL | FR = FR | FC = FC | BL = BL | BR = BR | LFE = LFE" />\r
+ <mix-config from-type="5.1+stereomix" to-types="matrix" mix="ML = 0.3204*FL + 0.293*FC + -0.293*BL + -0.293*BR | MR = 0.3204*FR + 0.293*FC + 0.293*BL + 0.293*BR" />\r
+ </mix-configs>\r
+</audio>\r
+-->\r
--- /dev/null
+CXX=g++
+PROTOC=protoc
+INSTALL=install
+EMBEDDED_BMUSB=no
+PKG_MODULES := Qt5Core Qt5Gui Qt5Widgets
+CXXFLAGS ?= -O2 -g -Wall # Will be overridden by environment.
+CXXFLAGS += -std=gnu++11 -fPIC $(shell pkg-config --cflags $(PKG_MODULES)) -pthread
+LDLIBS=$(shell pkg-config --libs $(PKG_MODULES)) -pthread
+
+OBJS_WITH_MOC = mainwindow.o
+OBJS += $(OBJS_WITH_MOC) main.o acmp_client.o
+OBJS += $(OBJS_WITH_MOC:.o=.moc.o)
+
+%.o: %.cpp
+ $(CXX) -MMD -MP $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
+%.o: %.cc
+ $(CXX) -MMD -MP $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
+
+ui_%.h: %.ui
+ uic $< -o $@
+
+%.moc.cpp: %.h
+ moc $< -o $@
+
+all: ultimatescore
+
+ultimatescore: $(OBJS)
+ $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS)
+
+mainwindow.o: ui_mainwindow.h
--- /dev/null
+#include "acmp_client.h"
+
+#include <functional>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+using namespace std;
+
+ACMPClient::ACMPClient(const string &host, int port)
+ : host(host), port(port) {}
+
+void ACMPClient::add_init_command(const string &cmd)
+{
+ init_commands.push_back(cmd + "\r\n");
+}
+
+void ACMPClient::start()
+{
+ t = thread(&ACMPClient::thread_func, this);
+}
+
+void ACMPClient::end()
+{
+ t.join();
+}
+
+void ACMPClient::send_command(const string &cmd)
+{
+ lock_guard<mutex> lock(mu);
+ queued_commands.push_back(cmd + "\r\n");
+}
+
+void ACMPClient::change_server(const string &host, int port)
+{
+ lock_guard<mutex> lock(mu);
+ queued_commands.push_back(""); // Marker for disconnect.
+ this->host = host;
+ this->port = port;
+}
+
+void ACMPClient::set_connection_callback(const std::function<void(bool)> &callback)
+{
+ connection_callback = callback;
+}
+
+namespace {
+
+int lookup_and_connect(const char *host, int port)
+{
+ addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ addrinfo *res;
+ char portstr[16];
+ snprintf(portstr, sizeof(portstr), "%d", port);
+ int err = getaddrinfo(host, portstr, &hints, &res);
+ if (err != 0) {
+ fprintf(stderr, "Lookup of %s:%d failed: %s\n", host, port, strerror(errno));
+ return -1;
+ }
+
+ for (addrinfo *p = res; p != NULL; p = p->ai_next) {
+ int sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+ if (sock == -1) {
+ perror("socket");
+ continue;
+ }
+
+ if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
+ perror("connect");
+ close(sock);
+ continue;
+ }
+
+ // Success!
+ freeaddrinfo(res);
+ return sock;
+ }
+
+ freeaddrinfo(res);
+ return -1;
+}
+
+} // namespace
+
+void ACMPClient::thread_func()
+{
+ if (connection_callback) {
+ connection_callback(false);
+ }
+ for ( ;; ) {
+ int sock, port_copy;
+ string host_copy;
+ {
+ lock_guard<mutex> lock(mu);
+ host_copy = host;
+ port_copy = port;
+ }
+ sock = lookup_and_connect(host_copy.c_str(), port_copy);
+ if (sock == -1) {
+ sleep(1);
+ continue;
+ }
+
+ int one = 1;
+ if (ioctl(sock, FIONBIO, &one) == 1) {
+ perror("ioctl(FIONBIO)");
+ close(sock);
+ sleep(1);
+ continue;
+ }
+
+ printf("Connected to CasparCG.\n");
+ if (connection_callback) {
+ connection_callback(true);
+ }
+
+ bool first = true;
+
+ for ( ;; ) {
+ vector<string> commands;
+ if (first) {
+ commands = init_commands;
+ first = false;
+ } else {
+ lock_guard<mutex> lock(mu);
+ swap(commands, queued_commands);
+ }
+
+ bool broken = false;
+ string buf;
+ for (const string &cmd : commands) {
+ buf += cmd;
+ if (cmd.empty()) {
+ printf("Closing CasparCG socket for reconnection.\n");
+ broken = true;
+ break;
+ }
+ }
+
+ if (broken) {
+ break;
+ }
+ if (!buf.empty()) {
+ printf("Writing: '%s'\n", buf.c_str());
+ }
+
+ size_t pos = 0;
+ do {
+ // Consume until there is no more.
+ char junk[1024];
+ int err = read(sock, junk, sizeof(junk));
+ if (err == -1) {
+ if (err == EAGAIN) {
+ perror("read");
+ broken = true;
+ break;
+ }
+ }
+ if (err == 0) {
+ // Closed.
+ printf("Server closed connection.\n");
+ broken = true;
+ break;
+ }
+ if (err > 0) {
+ // Try again.
+ junk[err] = 0;
+ printf("From server: '%s'\n", junk);
+ continue;
+ }
+
+ if (pos < buf.size()) {
+ // Now write as much as we can.
+ err = write(sock, buf.data() + pos, buf.size() - pos);
+ if (err == -1) {
+ perror("write");
+ broken = true;
+ break;
+ }
+ if (err == 0) {
+ // Uh-oh. Buffer full for some reason?
+ usleep(10000);
+ }
+ pos += err;
+ }
+ } while (pos < buf.size());
+
+ if (broken) {
+ break;
+ }
+ if (buf.empty()) {
+ usleep(100000);
+ continue;
+ }
+ }
+
+ close(sock);
+ if (connection_callback) {
+ connection_callback(false);
+ }
+ sleep(1);
+ }
+}
--- /dev/null
+#ifndef _ACMP_CLIENT_H
+#define _ACMP_CLIENT_H 1
+
+#include <functional>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <vector>
+
+class ACMPClient {
+public:
+ ACMPClient(const std::string &host, int port);
+
+ void add_init_command(const std::string &cmd);
+ void start();
+ void end();
+ void send_command(const std::string &cmd); // Thread-safe.
+ void change_server(const std::string &host, int port); // Thread-safe.
+ void set_connection_callback(const std::function<void(bool)> &callback);
+
+private:
+ void thread_func();
+
+ std::thread t;
+ std::vector<std::string> init_commands;
+ std::function<void(bool)> connection_callback;
+
+ std::mutex mu;
+ std::string host; // Protected by mu.
+ int port; // Protected by mu.
+ std::vector<std::string> queued_commands; // Protected by mu.
+};
+
+#endif // !defined(_ACMP_CLIENT_H)
--- /dev/null
+#include "acmp_client.h"
+#include "mainwindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
--- /dev/null
+#include "mainwindow.h"
+#include "post_to_main_thread.h"
+#include "ui_mainwindow.h"
+
+#include <stdlib.h>
+
+using namespace std;
+
+string escape_html(const string &str)
+{
+ string s = "";
+ for (char ch : str) {
+ if (ch == '<') {
+ s += "<";
+ } else if (ch == '>') {
+ s += ">";
+ } else if (ch == '&') {
+ s += "&";
+ } else {
+ s += ch;
+ }
+ }
+ return s;
+}
+
+string escape_unicode(const string &str)
+{
+ string s = "";
+ for (size_t pos = 0; pos < str.size(); ) {
+ wchar_t wc;
+ int len = mbtowc(&wc, str.data() + pos, str.size() - pos);
+ if (len == -1) {
+ wc = '?';
+ len = 1;
+ }
+ pos += len;
+
+ if (wc == '\\') {
+ s += "\\\\";
+ } else if (isprint(wc)) {
+ s += wc;
+ } else {
+ char buf[16];
+ snprintf(buf, sizeof(buf), "\\u%04x", wc);
+ s += buf;
+ }
+ }
+ return s;
+}
+
+string escape_quotes(const string &str)
+{
+ string s = "";
+ for (char ch : str) {
+ if (ch == '"' || ch == '\\') {
+ s += '\\';
+ }
+ s += ch;
+ }
+ return s;
+}
+
+string serialize_as_json(const map<string, string> ¶m)
+{
+ string s = "{";
+
+ bool first = true;
+ for (const auto &key_value : param) {
+ if (!first) s += ", ";
+ first = false;
+
+ s += '"';
+ s += escape_quotes(escape_unicode(key_value.first));
+ s += "\": \"";
+ s += escape_quotes(escape_unicode(key_value.second));
+ s += '"';
+ }
+ s += "}";
+ return s;
+}
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+ acmp = new ACMPClient("127.0.0.1", 5250);
+ acmp->add_init_command("MIXER 1 STRAIGHT_ALPHA_OUTPUT 1");
+ acmp->add_init_command("CG 1 ADD 0 \"score\" 1 \"<templateData></templateData>\"");
+ acmp->set_connection_callback([this](bool connected) {
+ string msg = connected ? "Connected" : "Not connected";
+ post_to_main_thread([this, msg]() {
+ ui->casparcg_connected_label->setText(QString::fromStdString(msg));
+ });
+ });
+
+ acmp->start();
+
+ connect(ui->casparcg_reconnect_btn, &QPushButton::clicked, this, &MainWindow::casparcg_reconnect_clicked);
+ connect(ui->set_initials_btn, &QPushButton::clicked, this, &MainWindow::set_initials_clicked);
+ connect(ui->set_color_btn, &QPushButton::clicked, this, &MainWindow::set_color_clicked);
+ connect(ui->set_score_btn, &QPushButton::clicked, this, &MainWindow::set_score_clicked);
+ connect(ui->set_all_scorebug_btn, &QPushButton::clicked, this, &MainWindow::set_all_scorebug_clicked);
+ connect(ui->goal_1_btn, &QPushButton::clicked, this, [this]() { add_goal(ui->score_1_box, 1); });
+ connect(ui->ungoal_1_btn, &QPushButton::clicked, this, [this]() { add_goal(ui->score_1_box, -1); });
+ connect(ui->goal_2_btn, &QPushButton::clicked, this, [this]() { add_goal(ui->score_2_box, 1); });
+ connect(ui->ungoal_2_btn, &QPushButton::clicked, this, [this]() { add_goal(ui->score_2_box, -1); });
+
+ connect(ui->set_clock_btn, &QPushButton::clicked, this, &MainWindow::set_clock_clicked);
+ connect(ui->start_and_show_clock_btn, &QPushButton::clicked, this, &MainWindow::start_and_show_clock_clicked);
+ connect(ui->stop_clock_btn, &QPushButton::clicked, this, &MainWindow::stop_clock_clicked);
+ connect(ui->show_clock_btn, &QPushButton::clicked, this, &MainWindow::show_clock_clicked);
+ connect(ui->hide_clock_btn, &QPushButton::clicked, this, &MainWindow::hide_clock_clicked);
+
+ connect(ui->set_comment_btn, &QPushButton::clicked, this, &MainWindow::set_comment_clicked);
+ connect(ui->set_and_show_comment_btn, &QPushButton::clicked, this, &MainWindow::set_and_show_comment_clicked);
+ connect(ui->hide_comment_btn, &QPushButton::clicked, this, &MainWindow::hide_comment_clicked);
+ connect(ui->set_and_show_autocomment_btn, &QPushButton::clicked, this, &MainWindow::set_and_show_autocomment_clicked);
+
+ connect(ui->show_lower_third_btn, &QPushButton::clicked, this, &MainWindow::show_lower_third_clicked);
+ connect(ui->hide_lower_third_btn, &QPushButton::clicked, this, &MainWindow::hide_lower_third_clicked);
+
+ autocomment_update();
+}
+
+MainWindow::~MainWindow()
+{
+ acmp->end();
+ delete ui;
+}
+
+void MainWindow::casparcg_reconnect_clicked()
+{
+ acmp->change_server(ui->casparcg_host_box->text().toStdString(),
+ stoi(ui->casparcg_port_box->text().toStdString()));
+}
+
+void MainWindow::set_initials_clicked()
+{
+ map<string, string> param;
+ param["team1"] = escape_html(ui->initials_1_edit->text().toStdString());
+ param["team2"] = escape_html(ui->initials_2_edit->text().toStdString());
+ acmp->send_command("cg 1 update 1 \"" + escape_quotes(serialize_as_json(param)) + "\"");
+ acmp->send_command("cg 1 invoke 1 setteams");
+}
+
+void MainWindow::set_color_clicked()
+{
+ map<string, string> param;
+ param["team1color"] = ui->color_1_edit->text().toStdString(); // Should maybe be escaped, but meh.
+ param["team2color"] = ui->color_2_edit->text().toStdString();
+ acmp->send_command("cg 1 update 1 \"" + escape_quotes(serialize_as_json(param)) + "\"");
+ acmp->send_command("cg 1 invoke 1 setcolors");
+}
+
+void MainWindow::set_score_clicked()
+{
+ map<string, string> param;
+ param["score1"] = to_string(ui->score_1_box->value());
+ param["score2"] = to_string(ui->score_2_box->value());
+ acmp->send_command("cg 1 update 1 \"" + escape_quotes(serialize_as_json(param)) + "\"");
+ acmp->send_command("cg 1 invoke 1 setscore");
+ autocomment_update();
+}
+
+void MainWindow::set_all_scorebug_clicked()
+{
+ set_initials_clicked();
+ set_color_clicked();
+ set_score_clicked();
+}
+
+void MainWindow::add_goal(QSpinBox *box, int delta)
+{
+ box->setValue(box->value() + delta);
+ set_score_clicked();
+}
+
+void MainWindow::set_clock_clicked()
+{
+ map<string, string> param;
+ param["clock_min"] = to_string(ui->clock_min_box->value());
+ param["clock_sec"] = to_string(ui->clock_sec_box->value());
+ acmp->send_command("cg 1 update 1 \"" + escape_quotes(serialize_as_json(param)) + "\"");
+ acmp->send_command("cg 1 invoke 1 setclockfromstate");
+}
+
+void MainWindow::start_and_show_clock_clicked()
+{
+ acmp->send_command("cg 1 invoke 1 startclock"); // Also shows.
+}
+
+void MainWindow::stop_clock_clicked()
+{
+ acmp->send_command("cg 1 invoke 1 stopclock");
+}
+
+void MainWindow::show_clock_clicked()
+{
+ acmp->send_command("cg 1 invoke 1 showclock");
+}
+
+void MainWindow::hide_clock_clicked()
+{
+ acmp->send_command("cg 1 invoke 1 hideclock");
+}
+
+void MainWindow::set_comment_clicked()
+{
+ map<string, string> param;
+ param["comment"] = ui->comment_edit->text().toStdString();
+ acmp->send_command("cg 1 update 1 \"" + escape_quotes(serialize_as_json(param)) + "\"");
+ acmp->send_command("cg 1 invoke 1 setcomment");
+}
+
+void MainWindow::set_and_show_comment_clicked()
+{
+ set_comment_clicked();
+ acmp->send_command("cg 1 invoke 1 showcomment");
+}
+
+void MainWindow::set_and_show_autocomment_clicked()
+{
+ ui->comment_edit->setText(ui->autocomment_edit->text());
+ set_and_show_comment_clicked();
+}
+
+void MainWindow::hide_comment_clicked()
+{
+ acmp->send_command("cg 1 invoke 1 hidecomment");
+}
+
+void MainWindow::show_lower_third_clicked()
+{
+ map<string, string> param;
+ param["text1"] = ui->lowerthird_heading_edit->text().toStdString();
+ param["text2"] = ui->lowerthird_subheading_edit->text().toStdString();
+ acmp->send_command("cg 1 update 1 \"" + escape_quotes(serialize_as_json(param)) + "\"");
+ acmp->send_command("cg 1 invoke 1 setandshowlowerthird");
+}
+
+void MainWindow::hide_lower_third_clicked()
+{
+ acmp->send_command("cg 1 invoke 1 hidelowerthird");
+}
+
+void MainWindow::autocomment_update()
+{
+ int score1 = ui->score_1_box->value();
+ int score2 = ui->score_2_box->value();
+ string msg;
+ if (abs(score1 - score2) >= 3) {
+ msg = "Game ends after this point";
+ } else if (score1 >= 12 || score2 >= 12) {
+ msg = "Point cap: First to 13";
+ } else {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "Pagacap: First to %d", max(score1, score2) + 1);
+ msg = buf;
+ }
+ ui->autocomment_edit->setText(QString::fromStdString(msg));
+}
--- /dev/null
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+#include "acmp_client.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class QSpinBox;
+
+class MainWindow : public QMainWindow
+{
+Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private:
+ void casparcg_reconnect_clicked();
+ void set_initials_clicked();
+ void set_color_clicked();
+ void set_score_clicked();
+ void set_all_scorebug_clicked();
+ void add_goal(QSpinBox *box, int delta);
+ void set_clock_clicked();
+ void start_and_show_clock_clicked();
+ void stop_clock_clicked();
+ void show_clock_clicked();
+ void hide_clock_clicked();
+ void set_comment_clicked();
+ void set_and_show_comment_clicked();
+ void hide_comment_clicked();
+ void set_and_show_autocomment_clicked();
+ void show_lower_third_clicked();
+ void hide_lower_third_clicked();
+ void autocomment_update();
+
+ Ui::MainWindow *ui;
+ ACMPClient *acmp;
+};
+
+#endif // MAINWINDOW_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>720</width>
+ <height>552</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <item>
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>CasparCG server:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="casparcg_host_box">
+ <property name="text">
+ <string>localhost</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="casparcg_port_box">
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>5250</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="casparcg_reconnect_btn">
+ <property name="text">
+ <string>Reconnect</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="casparcg_connected_label">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Not connected</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="4" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QPushButton" name="goal_2_btn">
+ <property name="text">
+ <string>+1 point</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="ungoal_2_btn">
+ <property name="text">
+ <string>-1 point</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Score</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QSpinBox" name="score_2_box"/>
+ </item>
+ <item row="3" column="3">
+ <widget class="QPushButton" name="set_score_btn">
+ <property name="text">
+ <string>Set</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>CSS color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="initials_1_edit">
+ <property name="text">
+ <string>PCL</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QPushButton" name="goal_1_btn">
+ <property name="text">
+ <string>+1 point</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="ungoal_1_btn">
+ <property name="text">
+ <string>-1 point</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="color_1_edit">
+ <property name="text">
+ <string>red</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QSpinBox" name="score_1_box"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Team 2</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Team 1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLineEdit" name="initials_2_edit">
+ <property name="text">
+ <string>TFK</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Initials</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="set_initials_btn">
+ <property name="text">
+ <string>Set</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLineEdit" name="color_2_edit">
+ <property name="text">
+ <string>yellow</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QPushButton" name="set_color_btn">
+ <property name="text">
+ <string>Set</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3">
+ <widget class="QPushButton" name="set_all_scorebug_btn">
+ <property name="text">
+ <string>Set all</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Set clock to:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="clock_min_box">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="value">
+ <number>25</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="clock_sec_box">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum">
+ <number>59</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="set_clock_btn">
+ <property name="text">
+ <string>Set</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="start_and_show_clock_btn">
+ <property name="text">
+ <string>Start (and show) clock</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stop_clock_btn">
+ <property name="text">
+ <string>Stop clock</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="show_clock_btn">
+ <property name="text">
+ <string>Show clock</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="hide_clock_btn">
+ <property name="text">
+ <string>Hide clock</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="comment_edit">
+ <property name="text">
+ <string>Pagacap: First to 9 points</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="set_comment_btn">
+ <property name="text">
+ <string>Set</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="set_and_show_comment_btn">
+ <property name="text">
+ <string>Set+show</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="hide_comment_btn">
+ <property name="text">
+ <string>Hide</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_11">
+ <item>
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Suggested autocomment if game ends right now:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="autocomment_edit">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="set_and_show_autocomment_btn">
+ <property name="text">
+ <string>Set+show</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Lower third heading (HTML allowed):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lowerthird_heading_edit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Lower third subheading (HTML allowed):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lowerthird_subheading_edit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <widget class="QPushButton" name="show_lower_third_btn">
+ <property name="text">
+ <string>Set + show lower third</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="hide_lower_third_btn">
+ <property name="text">
+ <string>Hide lower third</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+#ifndef _POST_TO_MAIN_THREAD_H
+#define _POST_TO_MAIN_THREAD_H 1
+
+#include <QApplication>
+#include <QObject>
+#include <memory>
+
+// http://stackoverflow.com/questions/21646467/how-to-execute-a-functor-in-a-given-thread-in-qt-gcd-style
+template<typename F>
+static inline void post_to_main_thread(F &&fun)
+{
+ QObject signalSource;
+ QObject::connect(&signalSource, &QObject::destroyed, qApp, std::move(fun));
+}
+
+#endif // !defined(_POST_TO_MAIN_THREAD_H)
--- /dev/null
+/********************************************************************************
+** Form generated from reading UI file 'mainwindow.ui'
+**
+** Created by: Qt User Interface Compiler version 5.7.1
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef UI_MAINWINDOW_H
+#define UI_MAINWINDOW_H
+
+#include <QtCore/QVariant>
+#include <QtWidgets/QAction>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QButtonGroup>
+#include <QtWidgets/QFrame>
+#include <QtWidgets/QGridLayout>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QSpinBox>
+#include <QtWidgets/QStatusBar>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_MainWindow
+{
+public:
+ QWidget *centralWidget;
+ QVBoxLayout *verticalLayout_2;
+ QVBoxLayout *verticalLayout;
+ QHBoxLayout *horizontalLayout_10;
+ QLabel *label_11;
+ QLineEdit *casparcg_host_box;
+ QLineEdit *casparcg_port_box;
+ QPushButton *casparcg_reconnect_btn;
+ QLabel *casparcg_connected_label;
+ QHBoxLayout *horizontalLayout_3;
+ QGridLayout *gridLayout;
+ QHBoxLayout *horizontalLayout_4;
+ QPushButton *goal_2_btn;
+ QPushButton *ungoal_2_btn;
+ QLabel *label_6;
+ QSpinBox *score_2_box;
+ QPushButton *set_score_btn;
+ QLabel *label_7;
+ QLineEdit *initials_1_edit;
+ QHBoxLayout *horizontalLayout_5;
+ QPushButton *goal_1_btn;
+ QPushButton *ungoal_1_btn;
+ QLineEdit *color_1_edit;
+ QSpinBox *score_1_box;
+ QLabel *label_4;
+ QLabel *label_3;
+ QLineEdit *initials_2_edit;
+ QLabel *label_5;
+ QPushButton *set_initials_btn;
+ QLineEdit *color_2_edit;
+ QPushButton *set_color_btn;
+ QPushButton *set_all_scorebug_btn;
+ QFrame *line_3;
+ QHBoxLayout *horizontalLayout_2;
+ QLabel *label;
+ QSpinBox *clock_min_box;
+ QLabel *label_2;
+ QSpinBox *clock_sec_box;
+ QPushButton *set_clock_btn;
+ QHBoxLayout *horizontalLayout;
+ QPushButton *start_and_show_clock_btn;
+ QPushButton *stop_clock_btn;
+ QPushButton *show_clock_btn;
+ QPushButton *hide_clock_btn;
+ QFrame *line_2;
+ QHBoxLayout *horizontalLayout_6;
+ QLabel *label_8;
+ QLineEdit *comment_edit;
+ QPushButton *set_comment_btn;
+ QPushButton *set_and_show_comment_btn;
+ QPushButton *hide_comment_btn;
+ QHBoxLayout *horizontalLayout_11;
+ QLabel *label_12;
+ QLineEdit *autocomment_edit;
+ QPushButton *set_and_show_autocomment_btn;
+ QFrame *line;
+ QHBoxLayout *horizontalLayout_7;
+ QLabel *label_9;
+ QLineEdit *lowerthird_heading_edit;
+ QHBoxLayout *horizontalLayout_8;
+ QLabel *label_10;
+ QLineEdit *lowerthird_subheading_edit;
+ QHBoxLayout *horizontalLayout_9;
+ QPushButton *show_lower_third_btn;
+ QPushButton *hide_lower_third_btn;
+ QStatusBar *statusBar;
+
+ void setupUi(QMainWindow *MainWindow)
+ {
+ if (MainWindow->objectName().isEmpty())
+ MainWindow->setObjectName(QStringLiteral("MainWindow"));
+ MainWindow->resize(720, 552);
+ centralWidget = new QWidget(MainWindow);
+ centralWidget->setObjectName(QStringLiteral("centralWidget"));
+ verticalLayout_2 = new QVBoxLayout(centralWidget);
+ verticalLayout_2->setSpacing(6);
+ verticalLayout_2->setContentsMargins(11, 11, 11, 11);
+ verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
+ verticalLayout = new QVBoxLayout();
+ verticalLayout->setSpacing(6);
+ verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setContentsMargins(6, 6, 6, 6);
+ horizontalLayout_10 = new QHBoxLayout();
+ horizontalLayout_10->setSpacing(6);
+ horizontalLayout_10->setObjectName(QStringLiteral("horizontalLayout_10"));
+ label_11 = new QLabel(centralWidget);
+ label_11->setObjectName(QStringLiteral("label_11"));
+
+ horizontalLayout_10->addWidget(label_11);
+
+ casparcg_host_box = new QLineEdit(centralWidget);
+ casparcg_host_box->setObjectName(QStringLiteral("casparcg_host_box"));
+
+ horizontalLayout_10->addWidget(casparcg_host_box);
+
+ casparcg_port_box = new QLineEdit(centralWidget);
+ casparcg_port_box->setObjectName(QStringLiteral("casparcg_port_box"));
+ casparcg_port_box->setMaximumSize(QSize(50, 16777215));
+
+ horizontalLayout_10->addWidget(casparcg_port_box);
+
+ casparcg_reconnect_btn = new QPushButton(centralWidget);
+ casparcg_reconnect_btn->setObjectName(QStringLiteral("casparcg_reconnect_btn"));
+
+ horizontalLayout_10->addWidget(casparcg_reconnect_btn);
+
+ casparcg_connected_label = new QLabel(centralWidget);
+ casparcg_connected_label->setObjectName(QStringLiteral("casparcg_connected_label"));
+ casparcg_connected_label->setMinimumSize(QSize(100, 0));
+ casparcg_connected_label->setAlignment(Qt::AlignCenter);
+
+ horizontalLayout_10->addWidget(casparcg_connected_label);
+
+
+ verticalLayout->addLayout(horizontalLayout_10);
+
+ horizontalLayout_3 = new QHBoxLayout();
+ horizontalLayout_3->setSpacing(6);
+ horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
+ gridLayout = new QGridLayout();
+ gridLayout->setSpacing(6);
+ gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ horizontalLayout_4 = new QHBoxLayout();
+ horizontalLayout_4->setSpacing(6);
+ horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
+ goal_2_btn = new QPushButton(centralWidget);
+ goal_2_btn->setObjectName(QStringLiteral("goal_2_btn"));
+
+ horizontalLayout_4->addWidget(goal_2_btn);
+
+ ungoal_2_btn = new QPushButton(centralWidget);
+ ungoal_2_btn->setObjectName(QStringLiteral("ungoal_2_btn"));
+
+ horizontalLayout_4->addWidget(ungoal_2_btn);
+
+
+ gridLayout->addLayout(horizontalLayout_4, 4, 2, 1, 1);
+
+ label_6 = new QLabel(centralWidget);
+ label_6->setObjectName(QStringLiteral("label_6"));
+
+ gridLayout->addWidget(label_6, 3, 0, 1, 1);
+
+ score_2_box = new QSpinBox(centralWidget);
+ score_2_box->setObjectName(QStringLiteral("score_2_box"));
+
+ gridLayout->addWidget(score_2_box, 3, 2, 1, 1);
+
+ set_score_btn = new QPushButton(centralWidget);
+ set_score_btn->setObjectName(QStringLiteral("set_score_btn"));
+
+ gridLayout->addWidget(set_score_btn, 3, 3, 1, 1);
+
+ label_7 = new QLabel(centralWidget);
+ label_7->setObjectName(QStringLiteral("label_7"));
+
+ gridLayout->addWidget(label_7, 2, 0, 1, 1);
+
+ initials_1_edit = new QLineEdit(centralWidget);
+ initials_1_edit->setObjectName(QStringLiteral("initials_1_edit"));
+
+ gridLayout->addWidget(initials_1_edit, 1, 1, 1, 1);
+
+ horizontalLayout_5 = new QHBoxLayout();
+ horizontalLayout_5->setSpacing(6);
+ horizontalLayout_5->setObjectName(QStringLiteral("horizontalLayout_5"));
+ goal_1_btn = new QPushButton(centralWidget);
+ goal_1_btn->setObjectName(QStringLiteral("goal_1_btn"));
+
+ horizontalLayout_5->addWidget(goal_1_btn);
+
+ ungoal_1_btn = new QPushButton(centralWidget);
+ ungoal_1_btn->setObjectName(QStringLiteral("ungoal_1_btn"));
+
+ horizontalLayout_5->addWidget(ungoal_1_btn);
+
+
+ gridLayout->addLayout(horizontalLayout_5, 4, 1, 1, 1);
+
+ color_1_edit = new QLineEdit(centralWidget);
+ color_1_edit->setObjectName(QStringLiteral("color_1_edit"));
+
+ gridLayout->addWidget(color_1_edit, 2, 1, 1, 1);
+
+ score_1_box = new QSpinBox(centralWidget);
+ score_1_box->setObjectName(QStringLiteral("score_1_box"));
+
+ gridLayout->addWidget(score_1_box, 3, 1, 1, 1);
+
+ label_4 = new QLabel(centralWidget);
+ label_4->setObjectName(QStringLiteral("label_4"));
+
+ gridLayout->addWidget(label_4, 0, 2, 1, 1);
+
+ label_3 = new QLabel(centralWidget);
+ label_3->setObjectName(QStringLiteral("label_3"));
+
+ gridLayout->addWidget(label_3, 0, 1, 1, 1);
+
+ initials_2_edit = new QLineEdit(centralWidget);
+ initials_2_edit->setObjectName(QStringLiteral("initials_2_edit"));
+
+ gridLayout->addWidget(initials_2_edit, 1, 2, 1, 1);
+
+ label_5 = new QLabel(centralWidget);
+ label_5->setObjectName(QStringLiteral("label_5"));
+
+ gridLayout->addWidget(label_5, 1, 0, 1, 1);
+
+ set_initials_btn = new QPushButton(centralWidget);
+ set_initials_btn->setObjectName(QStringLiteral("set_initials_btn"));
+
+ gridLayout->addWidget(set_initials_btn, 1, 3, 1, 1);
+
+ color_2_edit = new QLineEdit(centralWidget);
+ color_2_edit->setObjectName(QStringLiteral("color_2_edit"));
+
+ gridLayout->addWidget(color_2_edit, 2, 2, 1, 1);
+
+ set_color_btn = new QPushButton(centralWidget);
+ set_color_btn->setObjectName(QStringLiteral("set_color_btn"));
+
+ gridLayout->addWidget(set_color_btn, 2, 3, 1, 1);
+
+ set_all_scorebug_btn = new QPushButton(centralWidget);
+ set_all_scorebug_btn->setObjectName(QStringLiteral("set_all_scorebug_btn"));
+
+ gridLayout->addWidget(set_all_scorebug_btn, 4, 3, 1, 1);
+
+
+ horizontalLayout_3->addLayout(gridLayout);
+
+
+ verticalLayout->addLayout(horizontalLayout_3);
+
+ line_3 = new QFrame(centralWidget);
+ line_3->setObjectName(QStringLiteral("line_3"));
+ line_3->setFrameShape(QFrame::HLine);
+ line_3->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout->addWidget(line_3);
+
+ horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setSpacing(6);
+ horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ label = new QLabel(centralWidget);
+ label->setObjectName(QStringLiteral("label"));
+
+ horizontalLayout_2->addWidget(label);
+
+ clock_min_box = new QSpinBox(centralWidget);
+ clock_min_box->setObjectName(QStringLiteral("clock_min_box"));
+ QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(clock_min_box->sizePolicy().hasHeightForWidth());
+ clock_min_box->setSizePolicy(sizePolicy);
+ clock_min_box->setValue(25);
+
+ horizontalLayout_2->addWidget(clock_min_box);
+
+ label_2 = new QLabel(centralWidget);
+ label_2->setObjectName(QStringLiteral("label_2"));
+ QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ sizePolicy1.setHorizontalStretch(0);
+ sizePolicy1.setVerticalStretch(0);
+ sizePolicy1.setHeightForWidth(label_2->sizePolicy().hasHeightForWidth());
+ label_2->setSizePolicy(sizePolicy1);
+
+ horizontalLayout_2->addWidget(label_2);
+
+ clock_sec_box = new QSpinBox(centralWidget);
+ clock_sec_box->setObjectName(QStringLiteral("clock_sec_box"));
+ sizePolicy.setHeightForWidth(clock_sec_box->sizePolicy().hasHeightForWidth());
+ clock_sec_box->setSizePolicy(sizePolicy);
+ clock_sec_box->setMaximum(59);
+
+ horizontalLayout_2->addWidget(clock_sec_box);
+
+ set_clock_btn = new QPushButton(centralWidget);
+ set_clock_btn->setObjectName(QStringLiteral("set_clock_btn"));
+
+ horizontalLayout_2->addWidget(set_clock_btn);
+
+
+ verticalLayout->addLayout(horizontalLayout_2);
+
+ horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setSpacing(6);
+ horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ start_and_show_clock_btn = new QPushButton(centralWidget);
+ start_and_show_clock_btn->setObjectName(QStringLiteral("start_and_show_clock_btn"));
+
+ horizontalLayout->addWidget(start_and_show_clock_btn);
+
+ stop_clock_btn = new QPushButton(centralWidget);
+ stop_clock_btn->setObjectName(QStringLiteral("stop_clock_btn"));
+
+ horizontalLayout->addWidget(stop_clock_btn);
+
+ show_clock_btn = new QPushButton(centralWidget);
+ show_clock_btn->setObjectName(QStringLiteral("show_clock_btn"));
+
+ horizontalLayout->addWidget(show_clock_btn);
+
+ hide_clock_btn = new QPushButton(centralWidget);
+ hide_clock_btn->setObjectName(QStringLiteral("hide_clock_btn"));
+
+ horizontalLayout->addWidget(hide_clock_btn);
+
+
+ verticalLayout->addLayout(horizontalLayout);
+
+ line_2 = new QFrame(centralWidget);
+ line_2->setObjectName(QStringLiteral("line_2"));
+ line_2->setFrameShape(QFrame::HLine);
+ line_2->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout->addWidget(line_2);
+
+ horizontalLayout_6 = new QHBoxLayout();
+ horizontalLayout_6->setSpacing(6);
+ horizontalLayout_6->setObjectName(QStringLiteral("horizontalLayout_6"));
+ label_8 = new QLabel(centralWidget);
+ label_8->setObjectName(QStringLiteral("label_8"));
+
+ horizontalLayout_6->addWidget(label_8);
+
+ comment_edit = new QLineEdit(centralWidget);
+ comment_edit->setObjectName(QStringLiteral("comment_edit"));
+
+ horizontalLayout_6->addWidget(comment_edit);
+
+ set_comment_btn = new QPushButton(centralWidget);
+ set_comment_btn->setObjectName(QStringLiteral("set_comment_btn"));
+
+ horizontalLayout_6->addWidget(set_comment_btn);
+
+ set_and_show_comment_btn = new QPushButton(centralWidget);
+ set_and_show_comment_btn->setObjectName(QStringLiteral("set_and_show_comment_btn"));
+
+ horizontalLayout_6->addWidget(set_and_show_comment_btn);
+
+ hide_comment_btn = new QPushButton(centralWidget);
+ hide_comment_btn->setObjectName(QStringLiteral("hide_comment_btn"));
+
+ horizontalLayout_6->addWidget(hide_comment_btn);
+
+
+ verticalLayout->addLayout(horizontalLayout_6);
+
+ horizontalLayout_11 = new QHBoxLayout();
+ horizontalLayout_11->setSpacing(6);
+ horizontalLayout_11->setObjectName(QStringLiteral("horizontalLayout_11"));
+ label_12 = new QLabel(centralWidget);
+ label_12->setObjectName(QStringLiteral("label_12"));
+
+ horizontalLayout_11->addWidget(label_12);
+
+ autocomment_edit = new QLineEdit(centralWidget);
+ autocomment_edit->setObjectName(QStringLiteral("autocomment_edit"));
+ autocomment_edit->setEnabled(true);
+
+ horizontalLayout_11->addWidget(autocomment_edit);
+
+ set_and_show_autocomment_btn = new QPushButton(centralWidget);
+ set_and_show_autocomment_btn->setObjectName(QStringLiteral("set_and_show_autocomment_btn"));
+
+ horizontalLayout_11->addWidget(set_and_show_autocomment_btn);
+
+
+ verticalLayout->addLayout(horizontalLayout_11);
+
+ line = new QFrame(centralWidget);
+ line->setObjectName(QStringLiteral("line"));
+ line->setFrameShape(QFrame::HLine);
+ line->setFrameShadow(QFrame::Sunken);
+
+ verticalLayout->addWidget(line);
+
+ horizontalLayout_7 = new QHBoxLayout();
+ horizontalLayout_7->setSpacing(6);
+ horizontalLayout_7->setObjectName(QStringLiteral("horizontalLayout_7"));
+ label_9 = new QLabel(centralWidget);
+ label_9->setObjectName(QStringLiteral("label_9"));
+
+ horizontalLayout_7->addWidget(label_9);
+
+ lowerthird_heading_edit = new QLineEdit(centralWidget);
+ lowerthird_heading_edit->setObjectName(QStringLiteral("lowerthird_heading_edit"));
+
+ horizontalLayout_7->addWidget(lowerthird_heading_edit);
+
+
+ verticalLayout->addLayout(horizontalLayout_7);
+
+ horizontalLayout_8 = new QHBoxLayout();
+ horizontalLayout_8->setSpacing(6);
+ horizontalLayout_8->setObjectName(QStringLiteral("horizontalLayout_8"));
+ label_10 = new QLabel(centralWidget);
+ label_10->setObjectName(QStringLiteral("label_10"));
+
+ horizontalLayout_8->addWidget(label_10);
+
+ lowerthird_subheading_edit = new QLineEdit(centralWidget);
+ lowerthird_subheading_edit->setObjectName(QStringLiteral("lowerthird_subheading_edit"));
+
+ horizontalLayout_8->addWidget(lowerthird_subheading_edit);
+
+
+ verticalLayout->addLayout(horizontalLayout_8);
+
+ horizontalLayout_9 = new QHBoxLayout();
+ horizontalLayout_9->setSpacing(6);
+ horizontalLayout_9->setObjectName(QStringLiteral("horizontalLayout_9"));
+ show_lower_third_btn = new QPushButton(centralWidget);
+ show_lower_third_btn->setObjectName(QStringLiteral("show_lower_third_btn"));
+
+ horizontalLayout_9->addWidget(show_lower_third_btn);
+
+ hide_lower_third_btn = new QPushButton(centralWidget);
+ hide_lower_third_btn->setObjectName(QStringLiteral("hide_lower_third_btn"));
+
+ horizontalLayout_9->addWidget(hide_lower_third_btn);
+
+
+ verticalLayout->addLayout(horizontalLayout_9);
+
+
+ verticalLayout_2->addLayout(verticalLayout);
+
+ MainWindow->setCentralWidget(centralWidget);
+ statusBar = new QStatusBar(MainWindow);
+ statusBar->setObjectName(QStringLiteral("statusBar"));
+ MainWindow->setStatusBar(statusBar);
+
+ retranslateUi(MainWindow);
+
+ QMetaObject::connectSlotsByName(MainWindow);
+ } // setupUi
+
+ void retranslateUi(QMainWindow *MainWindow)
+ {
+ MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", Q_NULLPTR));
+ label_11->setText(QApplication::translate("MainWindow", "CasparCG server:", Q_NULLPTR));
+ casparcg_host_box->setText(QApplication::translate("MainWindow", "localhost", Q_NULLPTR));
+ casparcg_port_box->setText(QApplication::translate("MainWindow", "5250", Q_NULLPTR));
+ casparcg_reconnect_btn->setText(QApplication::translate("MainWindow", "Reconnect", Q_NULLPTR));
+ casparcg_connected_label->setText(QApplication::translate("MainWindow", "Not connected", Q_NULLPTR));
+ goal_2_btn->setText(QApplication::translate("MainWindow", "+1 point", Q_NULLPTR));
+ ungoal_2_btn->setText(QApplication::translate("MainWindow", "-1 point", Q_NULLPTR));
+ label_6->setText(QApplication::translate("MainWindow", "Score", Q_NULLPTR));
+ set_score_btn->setText(QApplication::translate("MainWindow", "Set", Q_NULLPTR));
+ label_7->setText(QApplication::translate("MainWindow", "CSS color", Q_NULLPTR));
+ initials_1_edit->setText(QApplication::translate("MainWindow", "PCL", Q_NULLPTR));
+ goal_1_btn->setText(QApplication::translate("MainWindow", "+1 point", Q_NULLPTR));
+ ungoal_1_btn->setText(QApplication::translate("MainWindow", "-1 point", Q_NULLPTR));
+ color_1_edit->setText(QApplication::translate("MainWindow", "red", Q_NULLPTR));
+ label_4->setText(QApplication::translate("MainWindow", "Team 2", Q_NULLPTR));
+ label_3->setText(QApplication::translate("MainWindow", "Team 1", Q_NULLPTR));
+ initials_2_edit->setText(QApplication::translate("MainWindow", "TFK", Q_NULLPTR));
+ label_5->setText(QApplication::translate("MainWindow", "Initials", Q_NULLPTR));
+ set_initials_btn->setText(QApplication::translate("MainWindow", "Set", Q_NULLPTR));
+ color_2_edit->setText(QApplication::translate("MainWindow", "yellow", Q_NULLPTR));
+ set_color_btn->setText(QApplication::translate("MainWindow", "Set", Q_NULLPTR));
+ set_all_scorebug_btn->setText(QApplication::translate("MainWindow", "Set all", Q_NULLPTR));
+ label->setText(QApplication::translate("MainWindow", "Set clock to:", Q_NULLPTR));
+ label_2->setText(QApplication::translate("MainWindow", ":", Q_NULLPTR));
+ set_clock_btn->setText(QApplication::translate("MainWindow", "Set", Q_NULLPTR));
+ start_and_show_clock_btn->setText(QApplication::translate("MainWindow", "Start (and show) clock", Q_NULLPTR));
+ stop_clock_btn->setText(QApplication::translate("MainWindow", "Stop clock", Q_NULLPTR));
+ show_clock_btn->setText(QApplication::translate("MainWindow", "Show clock", Q_NULLPTR));
+ hide_clock_btn->setText(QApplication::translate("MainWindow", "Hide clock", Q_NULLPTR));
+ label_8->setText(QApplication::translate("MainWindow", "Comment:", Q_NULLPTR));
+ comment_edit->setText(QApplication::translate("MainWindow", "Pagacap: First to 9 points", Q_NULLPTR));
+ set_comment_btn->setText(QApplication::translate("MainWindow", "Set", Q_NULLPTR));
+ set_and_show_comment_btn->setText(QApplication::translate("MainWindow", "Set+show", Q_NULLPTR));
+ hide_comment_btn->setText(QApplication::translate("MainWindow", "Hide", Q_NULLPTR));
+ label_12->setText(QApplication::translate("MainWindow", "Suggested autocomment if game ends right now:", Q_NULLPTR));
+ autocomment_edit->setText(QString());
+ set_and_show_autocomment_btn->setText(QApplication::translate("MainWindow", "Set+show", Q_NULLPTR));
+ label_9->setText(QApplication::translate("MainWindow", "Lower third heading (HTML allowed):", Q_NULLPTR));
+ label_10->setText(QApplication::translate("MainWindow", "Lower third subheading (HTML allowed):", Q_NULLPTR));
+ show_lower_third_btn->setText(QApplication::translate("MainWindow", "Set + show lower third", Q_NULLPTR));
+ hide_lower_third_btn->setText(QApplication::translate("MainWindow", "Hide lower third", Q_NULLPTR));
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class MainWindow: public Ui_MainWindow {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_MAINWINDOW_H
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="content-type" value="text/html; charset=utf-8" />
+ <meta charset="utf-8" />
+ <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
+ <style>
+* {
+ -webkit-box-sizing: border-box;
+ Box-Sizing: border-box;
+ -webkit-backface-visibility: hidden;
+ -webkit-transition: translate3d(0,0,0);
+}
+html, body {
+ width: 1280px;
+ height: 720px;
+ margin: 0;
+ padding: 0;
+ background: transparent;
+ overflow: hidden;
+ -webkit-font-smoothing: antialiased !important;
+}
+body {
+ font-family: 'Lato', sans-serif;
+ color: white;
+}
+
+/* Score */
+.scorebug {
+ position: fixed;
+ font-size: 25px;
+ left: 10px;
+ top: 10px;
+ border-collapse: collapse;
+ white-space: nowrap;
+ border: 3px solid black;
+ z-index: 1;
+}
+.scorebug td {
+ border: 3px solid #008;
+}
+.team1color, .team2color {
+ width: 15px;
+ margin: 5px;
+}
+.team1color {
+ background: red;
+}
+.team2color {
+ background: green;
+}
+.team1, .team2 {
+ font-weight: bold;
+ width: 100px;
+ text-align: center;
+ height: 35px;
+ background: #00a;
+}
+.score {
+ text-align: center;
+ background: #00c;
+ width: 110px;
+ height: 35px;
+}
+
+/* Clock, to the right of score */
+.clockbug {
+ position: fixed;
+ font-size: 25px;
+ left: 360px;
+ top: 10px;
+ border-collapse: collapse;
+ white-space: nowrap;
+ border: 3px solid black;
+}
+.clock {
+ border: 3px solid #008;
+ background: #00a;
+ text-align: center;
+ height: 35px;
+ width: 90px;
+}
+.clockbug-hidden {
+ -webkit-transform:translateX(-200%);
+}
+.clockbug-animate-in {
+ -webkit-animation: from-left 1s ease;
+}
+.clockbug-animate-out {
+ -webkit-animation: to-left 1s ease;
+ -webkit-transform:translateX(-200%);
+}
+
+/* Comment, below score */
+.commentbug {
+ position: fixed;
+ font-size: 20px;
+ left: 10px;
+ top: 52px;
+ border-collapse: collapse;
+ white-space: nowrap;
+ border: 3px solid black;
+}
+.comment {
+ border: 3px solid #008;
+ background: #00a;
+ text-align: center;
+ height: 30px;
+ width: 340px;
+}
+
+.commentbug-hidden {
+ -webkit-transform:translateY(-40px);
+}
+.commentbug-animate-in {
+ -webkit-animation: from-top 0.5s ease;
+}
+.commentbug-animate-out {
+ -webkit-animation: to-top 0.5s ease;
+ -webkit-transform:translateY(-40px);
+}
+
+/* Lower third */
+.lowerthird-headline {
+ position: fixed;
+ font-size: 40px;
+ left: 10px;
+ top: 520px;
+ border-collapse: collapse;
+ white-space: nowrap;
+ border: 2px solid #ccc;
+ height: 118px;
+ font-weight: bold;
+ width: 1050px;
+ /*background: linear-gradient(to right, #ccc, #fff 15px); */
+ background-image: url(lowerthird-bg.png);
+ color: black;
+ /* padding-top: 20px; */
+}
+.lowerthird-headline-hidden {
+ width: 0px;
+ border: 0px;
+}
+.lowerthird-headline-animate-in {
+ -webkit-animation: scale-out 1.0s;
+}
+.lowerthird-headline-animate-out {
+ -webkit-animation: scale-in 1.0s;
+}
+.lowerthird-headline-content {
+ padding-left: 20px;
+ position: absolute;
+}
+.lowerthird-headline-content-hidden {
+ clip: rect(0px,0px,200px,0px);
+}
+.lowerthird-headline-content-animate-in {
+ -webkit-animation: wipe-out 2.0s ease;
+}
+.lowerthird-headline-content-animate-out {
+ -webkit-animation: wipe-in 2.0s ease;
+ clip: rect(0px,0px,200px,0px);
+}
+.lowerthird-subheading {
+ position: fixed;
+ font-size: 24px;
+ left: 40px;
+ top: 637px;
+ height: 40px;
+ width: 500px;
+ border-collapse: collapse;
+ white-space: nowrap;
+ border: 1px solid black;
+ /*display: flex;
+ align-items: center; */
+ /*background: linear-gradient(to right, #44c, #33a 15px); */
+ background-image: url(lowerthird-bg2.png);
+}
+.lowerthird-subheading-hidden {
+ clip: rect(0px,0px,200px,0px);
+}
+.lowerthird-subheading-animate-in {
+ -webkit-animation: scale-out-small 1.6s ease;
+}
+.lowerthird-subheading-animate-out {
+ -webkit-animation: scale-in-small 1.6s ease;
+ width: 0px;
+ border-left: 0px;
+}
+.lowerthird-subheading-content {
+ position: absolute;
+ padding-left: 20px;
+}
+.lowerthird-subheading-content-hidden {
+ width: 0px;
+ border: 0px;
+}
+.lowerthird-subheading-content-animate-in {
+ -webkit-animation: wipe-out 2.2s ease;
+}
+.lowerthird-subheading-content-animate-out {
+ -webkit-animation: wipe-in 2.2s ease;
+ clip: rect(0px,0px,200px,0px);
+}
+
+/* these are hidden when actually run in casparcg */
+#area {
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 1280px;
+ height: 720px;
+ background: cyan;
+}
+#manualcontrols {
+ z-index: 3;
+ position: fixed;
+ top: 250px;
+}
+
+/* Animations */
+@-webkit-keyframes from-left {
+ 0% {
+ -webkit-transform:translateX(-200%);
+ }
+ 100% {
+ -webkit-transform:translateX(0);
+ }
+}
+@-webkit-keyframes to-left {
+ 0% {
+ -webkit-transform:translateX(0);
+ }
+ 100% {
+ -webkit-transform:translateX(-200%);
+ }
+}
+@-webkit-keyframes from-top {
+ 0% {
+ -webkit-transform:translateY(-40px);
+ }
+ 100% {
+ -webkit-transform:translateY(0);
+ }
+}
+@-webkit-keyframes to-top {
+ 0% {
+ -webkit-transform:translateY(0);
+ }
+ 100% {
+ -webkit-transform:translateY(-40px);
+ }
+}
+
+@-webkit-keyframes scale-out {
+ 0% {
+ width: 0px;
+ }
+ 100% {
+ width: 1050px;
+ }
+}
+@-webkit-keyframes scale-in {
+ 0% {
+ width: 1050px;
+ border: 2px solid #ccc;
+ }
+ 100% {
+ width: 0px;
+ border: 2px solid #ccc;
+ }
+}
+@-webkit-keyframes scale-out-small {
+ 0% {
+ width: 0px;
+ border: 0px;
+ }
+ 19.99% {
+ border: 0px;
+ }
+ 20% {
+ width: 0px;
+ border: 1px solid black;
+ }
+ 100% {
+ width: 500px;
+ }
+}
+@-webkit-keyframes scale-in-small {
+ 0% {
+ width: 500px;
+ border: 1px solid black;
+ }
+ 80% {
+ width: 0px;
+ border: 1px solid black;
+ }
+ 80.01% {
+ border: 0px;
+ }
+ 100% {
+ width: 0px;
+ border: 0px;
+ }
+}
+@-webkit-keyframes wipe-out {
+ 0% {
+ clip: rect(0px,0px,200px,0px);
+ }
+ 20% {
+ clip: rect(0px,0px,200px,0px);
+ }
+ 100% {
+ clip: rect(0px,1050px,200px,0px);
+ }
+}
+@-webkit-keyframes wipe-in {
+ 0% {
+ clip: rect(0px,1050px,200px,0px);
+ }
+ 20% { /* Not symmetrical! */
+ clip: rect(0px,0px,200px,0px);
+ }
+ 100% {
+ clip: rect(0px,0px,200px,0px);
+ }
+}
+ </style>
+ </head>
+ <body>
+ <div id="area"></div>
+ <table class="scorebug">
+ <tr>
+ <td class="team1color" id="team1color"></td>
+ <td class="team1" id="team1">PCL</td>
+ <td class="score" id="score">17 – 11</td>
+ <td class="team2" id="team2">NMBUI</td>
+ <td class="team2color" id="team2color"></td>
+ </tr>
+ </table>
+ <table class="clockbug clockbug-hidden" id="clockbug">
+ <tr>
+ <td class="clock" id="clock">25:00</td>
+ </tr>
+ </table>
+ <table class="commentbug commentbug-hidden" id="commentbug">
+ <tr>
+ <td class="comment" id="comment">Pagacap: First to 9 points</td>
+ </tr>
+ </table>
+ <div class="lowerthird-headline lowerthird-headline-hidden" id="lowerthird-headline"><div class="lowerthird-headline-content lowerthird-headline-content-hidden" id="lowerthird-headline-content">
+ John Doe<br>Ola Nordmann
+ </div></div>
+ <div class="lowerthird-subheading lowerthird-subheading-hidden" id="lowerthird-subheading"><div class="lowerthird-subheading-content lowerthird-subheading-content-hidden" id="lowerthird-subheading-content">
+ Commentators, Trøndisk 2016
+ </div></div>
+ <div id="manualcontrols">
+ <p>
+ <a href="javascript:startclock()">start clock</a>
+ <a href="javascript:stopclock()">stop clock</a>
+ <a href="javascript:setclock(25*60)">reset clock</a>
+ <a href="javascript:showclock()">show clock</a>
+ <a href="javascript:hideclock()">hide clock</a>
+ </p>
+ <p>
+ <a href="javascript:goalA()">goal team A</a>
+ <a href="javascript:goalB()">goal team B</a>
+ <a href="javascript:ungoalA()">ungoal team A</a>
+ <a href="javascript:ungoalB()">ungoal team B</a>
+ <a href="javascript:resetscore()">reset score</a>
+ </p>
+ <p>
+ <a href="javascript:showcomment()">show comment</a>
+ <a href="javascript:hidecomment()">hide comment</a>
+ </p>
+ <p>
+ <a href="javascript:showlowerthird()">show lower third</a>
+ <a href="javascript:hidelowerthird()">hide lower third</a>
+ </p>
+ </div>
+
+<script>
+var clock_running = false;
+var clock_visible = false;
+var comment_visible = false;
+var lowerthird_visible = false;
+var clock_left = 25 * 60;
+var scoreA = 0;
+var scoreB = 0;
+var clock_origin;
+var state = {};
+
+function setteams()
+{
+ document.getElementById('team1').innerHTML = state['team1'];
+ document.getElementById('team2').innerHTML = state['team2'];
+}
+
+function setcolors()
+{
+ document.getElementById('team1color').style.backgroundColor = state['team1color'];
+ document.getElementById('team2color').style.backgroundColor = state['team2color'];
+}
+
+function setscore()
+{
+ scoreA = state['score1'];
+ scoreB = state['score2'];
+ update_score();
+}
+
+function startclock()
+{
+ if (!clock_running) {
+ clock_origin = Date.now();
+ clock_running = true;
+ }
+ showclock();
+}
+
+function stopclock()
+{
+ if (!clock_running) return;
+ clock_left = time_left();
+ clock_origin = Date.now();
+ clock_running = false;
+}
+
+function setclock(amount)
+{
+ clock_left = amount;
+ clock_origin = Date.now();
+ update_clock();
+}
+
+function setclockfromstate()
+{
+ var amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
+ setclock(amount);
+}
+
+function showclock()
+{
+ if (clock_visible) return;
+ var clockbug = document.getElementById('clockbug');
+ clockbug.className = 'clockbug clockbug-animate-in';
+ clock_visible = true;
+}
+
+function hideclock()
+{
+ if (!clock_visible) return;
+ var clockbug = document.getElementById('clockbug');
+ clockbug.className = 'clockbug clockbug-animate-out';
+ clock_visible = false;
+}
+
+function setcomment()
+{
+ document.getElementById('comment').innerHTML = state['comment'];
+}
+
+function showcomment()
+{
+ if (comment_visible) return;
+ var commentbug = document.getElementById('commentbug');
+ commentbug.className = 'commentbug commentbug-animate-in';
+ comment_visible = true;
+}
+
+function hidecomment()
+{
+ if (!comment_visible) return;
+ var commentbug = document.getElementById('commentbug');
+ commentbug.className = 'commentbug commentbug-animate-out';
+ comment_visible = false;
+}
+
+function showlowerthird()
+{
+ if (lowerthird_visible) return;
+
+ // With no flexbox, this is how it has to be...
+ var f = document.getElementById('lowerthird-headline');
+ var g = document.getElementById('lowerthird-headline-content');
+ f.style.paddingTop = Math.round((f.clientHeight - g.clientHeight) / 2) + 'px';
+
+ f = document.getElementById('lowerthird-subheading');
+ g = document.getElementById('lowerthird-subheading-content');
+ f.style.paddingTop = Math.round((f.clientHeight - g.clientHeight) / 2) + 'px';
+
+ document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-animate-in';
+ document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-in';
+ document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-in';
+ document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-in';
+ lowerthird_visible = true;
+}
+
+function setandshowlowerthird()
+{
+ document.getElementById('lowerthird-headline-content').innerHTML = state['text1'];
+ document.getElementById('lowerthird-subheading-content').innerHTML = state['text2'];
+ showlowerthird();
+}
+
+function hidelowerthird()
+{
+ if (!lowerthird_visible) return;
+ document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-hidden lowerthird-headline-animate-out';
+ document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-out';
+ document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-out';
+ document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-out';
+ lowerthird_visible = false;
+}
+
+function time_left()
+{
+ var elapsed = (Date.now() - clock_origin) * 1e-3;
+ if (elapsed > clock_left) return 0;
+ return Math.ceil(clock_left - elapsed);
+}
+
+function update_clock()
+{
+ var left = time_left();
+ var min = Math.floor(left / 60);
+ var sec = left % 60;
+
+ if (sec < 10) sec = "0" + sec;
+ document.getElementById('clock').innerHTML = min + ":" + sec;
+}
+
+function goalA()
+{
+ ++scoreA;
+ update_score();
+}
+
+function goalB()
+{
+ ++scoreB;
+ update_score();
+}
+
+function ungoalA()
+{
+ if (scoreA > 0) --scoreA;
+ update_score();
+}
+
+function ungoalB()
+{
+ if (scoreB > 0) --scoreB;
+ update_score();
+}
+
+function resetscore()
+{
+ scoreA = scoreB = 0;
+ update_score();
+}
+
+function update_score()
+{
+ document.getElementById('score').innerHTML = scoreA + " – " + scoreB;
+}
+
+/* called by caspar only */
+function play()
+{
+ document.getElementById('manualcontrols').style.display = 'none';
+ document.getElementById('area').style.display = 'none';
+
+ // Old CEF workaround
+ document.getElementById('lowerthird-subheading').style.top = '638px';
+}
+
+function update(v)
+{
+ console.log('[[[' + v + ']]]');
+ var j = JSON.parse(v);
+ for(var key in j) state[key] = j[key];
+}
+
+setInterval(function() {
+ if (clock_running) {
+ update_clock();
+ }
+}, 100);
+update_score();
+
+//play();
+//startclock();
+</script>
+ </body>
+</html>