{\rtf1\ansi\ansicpg1252\cocoartf2761 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 .AppleSystemUIFontMonospaced-Regular;\f1\fnil\fcharset0 .AppleSystemUIFontMonospaced-RegularItalic;} {\colortbl;\red255\green255\blue255;\red155\green162\blue177;\red36\green36\blue35;\red214\green85\blue98; \red197\green136\blue83;\red136\green185\blue102;\red81\green157\blue235;\red184\green93\blue213;\red74\green80\blue93; } {\*\expandedcolortbl;;\cssrgb\c67059\c69804\c74902;\cssrgb\c18824\c18824\c18039;\cssrgb\c87843\c42353\c45882; \cssrgb\c81961\c60392\c40000;\cssrgb\c59608\c76471\c47451;\cssrgb\c38039\c68627\c93725;\cssrgb\c77647\c47059\c86667;\cssrgb\c36078\c38824\c43922; } \paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0 \deftab720 \pard\pardeftab720\partightenfactor0 \f0\fs28 \cf2 \cb3 \expnd0\expndtw0\kerning0 \outl0\strokewidth0 \strokec2 \ <\cf4 \strokec4 html \cf5 \strokec5 lang\cf2 \strokec2 ="\cf6 \strokec6 en\cf2 \strokec2 ">\ <\cf4 \strokec4 head\cf2 \strokec2 >\ <\cf4 \strokec4 meta \cf5 \strokec5 charset\cf2 \strokec2 ="\cf6 \strokec6 UTF-8\cf2 \strokec2 "\cf4 \strokec4 \cf2 \strokec2 />\ <\cf4 \strokec4 title\cf2 \strokec2 >Split-Flap 15\'d77\ <\cf4 \strokec4 link \cf5 \strokec5 href\cf2 \strokec2 ="\cf6 \strokec6 https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 rel\cf2 \strokec2 ="\cf6 \strokec6 stylesheet\cf2 \strokec2 ">\ <\cf4 \strokec4 style\cf2 \strokec2 >\ \cf6 \strokec6 :root\cf2 \strokec2 \{\ \cf7 \strokec7 --bg\cf2 \strokec2 : #000;\ \cf7 \strokec7 --fg\cf2 \strokec2 : #fff;\ \cf7 \strokec7 --line\cf2 \strokec2 : #222;\ \cf7 \strokec7 --accent\cf2 \strokec2 : #999;\ \cf7 \strokec7 --panel-bg\cf2 \strokec2 : #050505;\ \cf7 \strokec7 --panel-border\cf2 \strokec2 : #333;\ \cf7 \strokec7 --cursor\cf2 \strokec2 : #ffffff;\ \}\ \ \cf6 \strokec6 body\cf2 \strokec2 \{\ \cf4 \strokec4 margin\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 background\cf2 \strokec2 : #000;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 font-family\cf2 \strokec2 : -apple-system, BlinkMacSystemFont, \cf6 \strokec6 "SF Pro Text"\cf2 \strokec2 , system-ui, sans-serif;\ \}\ \ \cf6 \strokec6 .app\cf2 \strokec2 \{\ \cf4 \strokec4 min-height\cf2 \strokec2 : \cf5 \strokec5 100\cf2 \strokec2 vh;\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 flex-direction\cf2 \strokec2 : column;\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --bg\cf2 \strokec2 );\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .app.invert\cf2 \strokec2 \{\ \cf7 \strokec7 --bg\cf2 \strokec2 : #ffffff;\ \cf7 \strokec7 --fg\cf2 \strokec2 : #000000;\ \cf7 \strokec7 --line\cf2 \strokec2 : #dddddd;\ \cf7 \strokec7 --panel-bg\cf2 \strokec2 : #f5f5f5;\ \cf7 \strokec7 --panel-border\cf2 \strokec2 : #cccccc;\ \cf7 \strokec7 --accent\cf2 \strokec2 : #666666;\ \cf7 \strokec7 --cursor\cf2 \strokec2 : #000000;\ \}\ \ \cf6 \strokec6 .display-wrapper\cf2 \strokec2 \{\ \cf4 \strokec4 flex\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 ;\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 align-items\cf2 \strokec2 : center;\ \cf4 \strokec4 justify-content\cf2 \strokec2 : center;\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 8\cf2 \strokec2 vh \cf5 \strokec5 24\cf2 \strokec2 px \cf5 \strokec5 32\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .display\cf2 \strokec2 \{\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 flex-direction\cf2 \strokec2 : column;\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 8\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .row\cf2 \strokec2 \{\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 justify-content\cf2 \strokec2 : center;\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 6\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .flap\cf2 \strokec2 \{\ \cf4 \strokec4 position\cf2 \strokec2 : relative;\ \cf4 \strokec4 width\cf2 \strokec2 : \cf5 \strokec5 28\cf2 \strokec2 px;\ \cf4 \strokec4 height\cf2 \strokec2 : \cf5 \strokec5 48\cf2 \strokec2 px;\ \cf4 \strokec4 perspective\cf2 \strokec2 : \cf5 \strokec5 400\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .half\cf2 \strokec2 \{\ \cf4 \strokec4 position\cf2 \strokec2 : absolute;\ \cf4 \strokec4 left\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 right\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 height\cf2 \strokec2 : \cf5 \strokec5 100\cf2 \strokec2 %;\ \cf4 \strokec4 overflow\cf2 \strokec2 : hidden;\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 justify-content\cf2 \strokec2 : center;\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --bg\cf2 \strokec2 );\ \cf4 \strokec4 backface-visibility\cf2 \strokec2 : hidden;\ \}\ \ \cf6 \strokec6 .half.top\cf2 \strokec2 \{\ \cf4 \strokec4 top\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 transform-origin\cf2 \strokec2 : bottom;\ \cf4 \strokec4 align-items\cf2 \strokec2 : center;\ \cf4 \strokec4 clip-path\cf2 \strokec2 : \cf7 \strokec7 inset\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 \cf5 \strokec5 50\cf2 \strokec2 % \cf5 \strokec5 0\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .half.bottom\cf2 \strokec2 \{\ \cf4 \strokec4 bottom\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 transform-origin\cf2 \strokec2 : top;\ \cf4 \strokec4 align-items\cf2 \strokec2 : center;\ \cf4 \strokec4 clip-path\cf2 \strokec2 : \cf7 \strokec7 inset\cf2 \strokec2 (\cf5 \strokec5 50\cf2 \strokec2 % \cf5 \strokec5 0\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .char\cf2 \strokec2 \{\ \cf4 \strokec4 font-weight\cf2 \strokec2 : \cf5 \strokec5 700\cf2 \strokec2 ;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 18\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.16\cf2 \strokec2 em;\ \cf4 \strokec4 line-height\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 ;\ \}\ \ \cf6 \strokec6 .font-clean .char\cf2 \strokec2 \{\ \cf4 \strokec4 font-family\cf2 \strokec2 : \cf6 \strokec6 "Helvetica Neue"\cf2 \strokec2 , -apple-system, BlinkMacSystemFont, system-ui, sans-serif;\ \}\ \ \cf6 \strokec6 .font-retro .char\cf2 \strokec2 \{\ \cf4 \strokec4 font-family\cf2 \strokec2 : \cf6 \strokec6 "Press Start 2P"\cf2 \strokec2 , system-ui, sans-serif;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 11\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.25\cf2 \strokec2 em;\ \}\ \ \cf6 \strokec6 .flip-top\cf2 \strokec2 \{\ \cf4 \strokec4 animation\cf2 \strokec2 : flip-top \cf5 \strokec5 0.1\cf2 \strokec2 s ease-in-out forwards;\ \}\ \ \cf6 \strokec6 .flip-bottom\cf2 \strokec2 \{\ \cf4 \strokec4 animation\cf2 \strokec2 : flip-bottom \cf5 \strokec5 0.1\cf2 \strokec2 s ease-in-out forwards;\ \}\ \ \cf5 \strokec5 @keyframes flip-top\cf2 \strokec2 \{\ \cf6 \strokec6 0%\cf2 \strokec2 \{ \cf4 \strokec4 transform\cf2 \strokec2 : \cf7 \strokec7 rotateX\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 deg); \}\ \cf6 \strokec6 100%\cf2 \strokec2 \{ \cf4 \strokec4 transform\cf2 \strokec2 : \cf7 \strokec7 rotateX\cf2 \strokec2 (\cf5 \strokec5 90\cf2 \strokec2 deg); \cf4 \strokec4 opacity\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ; \}\ \}\ \ \cf5 \strokec5 @keyframes flip-bottom\cf2 \strokec2 \{\ \cf6 \strokec6 0%\cf2 \strokec2 \{ \cf4 \strokec4 transform\cf2 \strokec2 : \cf7 \strokec7 rotateX\cf2 \strokec2 (\cf5 \strokec5 -90\cf2 \strokec2 deg); \cf4 \strokec4 opacity\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ; \}\ \cf6 \strokec6 100%\cf2 \strokec2 \{ \cf4 \strokec4 transform\cf2 \strokec2 : \cf7 \strokec7 rotateX\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 deg); \cf4 \strokec4 opacity\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 ; \}\ \}\ \ \cf6 \strokec6 .panel\cf2 \strokec2 \{\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-bg\cf2 \strokec2 );\ \cf4 \strokec4 border-top\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px \cf5 \strokec5 24\cf2 \strokec2 px \cf5 \strokec5 18\cf2 \strokec2 px;\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 flex-direction\cf2 \strokec2 : column;\ \cf4 \strokec4 max-height\cf2 \strokec2 : \cf5 \strokec5 60\cf2 \strokec2 vh;\ \cf4 \strokec4 overflow-y\cf2 \strokec2 : auto;\ \}\ \ \cf6 \strokec6 .panel-inner\cf2 \strokec2 \{\ \cf4 \strokec4 max-width\cf2 \strokec2 : \cf5 \strokec5 880\cf2 \strokec2 px;\ \cf4 \strokec4 margin\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 auto;\ \cf4 \strokec4 width\cf2 \strokec2 : \cf5 \strokec5 100\cf2 \strokec2 %;\ \}\ \ \cf6 \strokec6 .bottom-settings\cf2 \strokec2 \{\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 justify-content\cf2 \strokec2 : space-between;\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 24\cf2 \strokec2 px;\ \cf4 \strokec4 margin-bottom\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 11\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.14\cf2 \strokec2 em;\ \cf4 \strokec4 text-transform\cf2 \strokec2 : uppercase;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .bottom-group\cf2 \strokec2 \{\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 align-items\cf2 \strokec2 : center;\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 8\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .bottom-label\cf2 \strokec2 \{\ \cf4 \strokec4 opacity\cf2 \strokec2 : \cf5 \strokec5 0.7\cf2 \strokec2 ;\ \}\ \ \cf6 \strokec6 .toggle-btn\cf2 \strokec2 \{\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 999\cf2 \strokec2 px;\ \cf4 \strokec4 border\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 4\cf2 \strokec2 px \cf5 \strokec5 10\cf2 \strokec2 px \cf5 \strokec5 5\cf2 \strokec2 px;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.16\cf2 \strokec2 em;\ \cf4 \strokec4 text-transform\cf2 \strokec2 : uppercase;\ \cf4 \strokec4 cursor\cf2 \strokec2 : pointer;\ \cf4 \strokec4 background\cf2 \strokec2 : transparent;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 user-select\cf2 \strokec2 : none;\ \}\ \ \cf6 \strokec6 .toggle-btn.active\cf2 \strokec2 \{\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --bg\cf2 \strokec2 );\ \cf4 \strokec4 border-color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .add-screen-btn\cf2 \strokec2 \{\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 999\cf2 \strokec2 px;\ \cf4 \strokec4 border\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 4\cf2 \strokec2 px \cf5 \strokec5 10\cf2 \strokec2 px \cf5 \strokec5 5\cf2 \strokec2 px;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.16\cf2 \strokec2 em;\ \cf4 \strokec4 text-transform\cf2 \strokec2 : uppercase;\ \cf4 \strokec4 cursor\cf2 \strokec2 : pointer;\ \cf4 \strokec4 background\cf2 \strokec2 : transparent;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 user-select\cf2 \strokec2 : none;\ \}\ \ \cf6 \strokec6 .add-screen-btn:hover\cf2 \strokec2 \{\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --bg\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .screen-label\cf2 \strokec2 \{\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 11\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.22\cf2 \strokec2 em;\ \cf4 \strokec4 text-transform\cf2 \strokec2 : uppercase;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 margin-bottom\cf2 \strokec2 : \cf5 \strokec5 8\cf2 \strokec2 px;\ \cf4 \strokec4 margin-top\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .screen-label:first-of-type\cf2 \strokec2 \{\ \cf4 \strokec4 margin-top\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \}\ \ \cf6 \strokec6 .screen-card\cf2 \strokec2 \{\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px;\ \cf4 \strokec4 border\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px \cf5 \strokec5 16\cf2 \strokec2 px \cf5 \strokec5 12\cf2 \strokec2 px;\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 rgba\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 , \cf5 \strokec5 0\cf2 \strokec2 , \cf5 \strokec5 0\cf2 \strokec2 , \cf5 \strokec5 0.35\cf2 \strokec2 );\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 flex-direction\cf2 \strokec2 : column;\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px;\ \cf4 \strokec4 margin-bottom\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .app.invert .screen-card\cf2 \strokec2 \{\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 rgba\cf2 \strokec2 (\cf5 \strokec5 255\cf2 \strokec2 , \cf5 \strokec5 255\cf2 \strokec2 , \cf5 \strokec5 255\cf2 \strokec2 , \cf5 \strokec5 0.5\cf2 \strokec2 );\ \}\ \ \cf6 \strokec6 .screen-text-wrapper\cf2 \strokec2 \{\ \cf4 \strokec4 position\cf2 \strokec2 : relative;\ \cf4 \strokec4 min-height\cf2 \strokec2 : \cf5 \strokec5 120\cf2 \strokec2 px;\ \cf4 \strokec4 font-family\cf2 \strokec2 : \cf6 \strokec6 "SF Mono"\cf2 \strokec2 , Menlo, Monaco, Consolas, monospace;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 13\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.14\cf2 \strokec2 em;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \}\ \ \cf6 \strokec6 .text-input\cf2 \strokec2 \{\ \cf4 \strokec4 width\cf2 \strokec2 : \cf5 \strokec5 100\cf2 \strokec2 %;\ \cf4 \strokec4 height\cf2 \strokec2 : \cf5 \strokec5 100\cf2 \strokec2 %;\ \cf4 \strokec4 background\cf2 \strokec2 : transparent;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 font-family\cf2 \strokec2 : \cf6 \strokec6 "SF Mono"\cf2 \strokec2 , Menlo, Monaco, Consolas, monospace;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 13\cf2 \strokec2 px;\ \cf4 \strokec4 letter-spacing\cf2 \strokec2 : \cf5 \strokec5 0.14\cf2 \strokec2 em;\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 margin\cf2 \strokec2 : \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf4 \strokec4 line-height\cf2 \strokec2 : \cf5 \strokec5 1.4\cf2 \strokec2 ;\ \cf4 \strokec4 caret-color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --cursor\cf2 \strokec2 );\ \cf4 \strokec4 border\cf2 \strokec2 : none;\ \cf4 \strokec4 outline\cf2 \strokec2 : none;\ \cf4 \strokec4 resize\cf2 \strokec2 : none;\ \}\ \ \cf6 \strokec6 .text-input:focus\cf2 \strokec2 \{\ \cf4 \strokec4 outline\cf2 \strokec2 : none;\ \cf4 \strokec4 border\cf2 \strokec2 : none;\ \}\ \ \cf6 \strokec6 .underline\cf2 \strokec2 \{\ \cf4 \strokec4 height\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px;\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 margin-top\cf2 \strokec2 : \cf5 \strokec5 6\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .screen-footer\cf2 \strokec2 \{\ \cf4 \strokec4 display\cf2 \strokec2 : flex;\ \cf4 \strokec4 justify-content\cf2 \strokec2 : space-between;\ \cf4 \strokec4 align-items\cf2 \strokec2 : center;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 11\cf2 \strokec2 px;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .duration-input-wrap\cf2 \strokec2 \{\ \cf4 \strokec4 display\cf2 \strokec2 : inline-flex;\ \cf4 \strokec4 align-items\cf2 \strokec2 : center;\ \cf4 \strokec4 gap\cf2 \strokec2 : \cf5 \strokec5 6\cf2 \strokec2 px;\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 999\cf2 \strokec2 px;\ \cf4 \strokec4 border\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 4\cf2 \strokec2 px \cf5 \strokec5 8\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .duration-input-wrap input\cf2 \strokec2 \{\ \cf4 \strokec4 width\cf2 \strokec2 : \cf5 \strokec5 40\cf2 \strokec2 px;\ \cf4 \strokec4 background\cf2 \strokec2 : transparent;\ \cf4 \strokec4 border\cf2 \strokec2 : none;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 font-weight\cf2 \strokec2 : \cf5 \strokec5 600\cf2 \strokec2 ;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 11\cf2 \strokec2 px;\ \cf4 \strokec4 text-align\cf2 \strokec2 : center;\ \cf4 \strokec4 outline\cf2 \strokec2 : none;\ \}\ \ \cf6 \strokec6 .clock-icon\cf2 \strokec2 \{\ \cf4 \strokec4 width\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px;\ \cf4 \strokec4 height\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px;\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 50\cf2 \strokec2 %;\ \cf4 \strokec4 border\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 position\cf2 \strokec2 : relative;\ \}\ \ \cf6 \strokec6 .clock-icon::after\cf2 \strokec2 \{\ \cf4 \strokec4 content\cf2 \strokec2 : \cf6 \strokec6 ""\cf2 \strokec2 ;\ \cf4 \strokec4 position\cf2 \strokec2 : absolute;\ \cf4 \strokec4 width\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px;\ \cf4 \strokec4 height\cf2 \strokec2 : \cf5 \strokec5 5\cf2 \strokec2 px;\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 top\cf2 \strokec2 : \cf5 \strokec5 3\cf2 \strokec2 px;\ \cf4 \strokec4 left\cf2 \strokec2 : \cf5 \strokec5 6\cf2 \strokec2 px;\ \}\ \ \cf6 \strokec6 .remove-btn\cf2 \strokec2 \{\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 4\cf2 \strokec2 px \cf5 \strokec5 8\cf2 \strokec2 px;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px;\ \cf4 \strokec4 background\cf2 \strokec2 : transparent;\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --accent\cf2 \strokec2 );\ \cf4 \strokec4 border\cf2 \strokec2 : \cf5 \strokec5 1\cf2 \strokec2 px solid \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --panel-border\cf2 \strokec2 );\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 4\cf2 \strokec2 px;\ \cf4 \strokec4 cursor\cf2 \strokec2 : pointer;\ \cf4 \strokec4 text-transform\cf2 \strokec2 : uppercase;\ \}\ \ \cf6 \strokec6 .remove-btn:hover\cf2 \strokec2 \{\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 rgba\cf2 \strokec2 (\cf5 \strokec5 255\cf2 \strokec2 , \cf5 \strokec5 0\cf2 \strokec2 , \cf5 \strokec5 0\cf2 \strokec2 , \cf5 \strokec5 0.1\cf2 \strokec2 );\ \cf4 \strokec4 color\cf2 \strokec2 : #ff6666;\ \cf4 \strokec4 border-color\cf2 \strokec2 : #ff6666;\ \}\ \ \cf6 \strokec6 .fullscreen-button\cf2 \strokec2 \{\ \cf4 \strokec4 position\cf2 \strokec2 : fixed;\ \cf4 \strokec4 top\cf2 \strokec2 : \cf5 \strokec5 20\cf2 \strokec2 px;\ \cf4 \strokec4 right\cf2 \strokec2 : \cf5 \strokec5 20\cf2 \strokec2 px;\ \cf4 \strokec4 background\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --fg\cf2 \strokec2 );\ \cf4 \strokec4 color\cf2 \strokec2 : \cf7 \strokec7 var\cf2 \strokec2 (\cf7 \strokec7 --bg\cf2 \strokec2 );\ \cf4 \strokec4 border\cf2 \strokec2 : none;\ \cf4 \strokec4 padding\cf2 \strokec2 : \cf5 \strokec5 10\cf2 \strokec2 px \cf5 \strokec5 15\cf2 \strokec2 px;\ \cf4 \strokec4 border-radius\cf2 \strokec2 : \cf5 \strokec5 6\cf2 \strokec2 px;\ \cf4 \strokec4 cursor\cf2 \strokec2 : pointer;\ \cf4 \strokec4 font-size\cf2 \strokec2 : \cf5 \strokec5 14\cf2 \strokec2 px;\ \cf4 \strokec4 font-weight\cf2 \strokec2 : bold;\ \cf4 \strokec4 z-index\cf2 \strokec2 : \cf5 \strokec5 10000\cf2 \strokec2 ;\ \}\ \ \cf6 \strokec6 .fullscreen-button:hover\cf2 \strokec2 \{\ \cf4 \strokec4 opacity\cf2 \strokec2 : \cf5 \strokec5 0.8\cf2 \strokec2 ;\ \}\ \ \ <\cf4 \strokec4 body\cf2 \strokec2 >\ <\cf4 \strokec4 div \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 app\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 app font-clean\cf2 \strokec2 ">\ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 display-wrapper\cf2 \strokec2 ">\ <\cf4 \strokec4 div \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 display\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 display\cf2 \strokec2 ">\ \ <\cf4 \strokec4 button \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 fullscreenBtn\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 fullscreen-button\cf2 \strokec2 ">Fullscreen\ \ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 panel\cf2 \strokec2 ">\ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 panel-inner\cf2 \strokec2 ">\ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 bottom-settings\cf2 \strokec2 ">\ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 bottom-group\cf2 \strokec2 ">\ <\cf4 \strokec4 span \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 bottom-label\cf2 \strokec2 ">Font\ <\cf4 \strokec4 button \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 fontCleanBtn\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 toggle-btn active\cf2 \strokec2 ">Clean\ <\cf4 \strokec4 button \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 fontRetroBtn\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 toggle-btn\cf2 \strokec2 ">Retro\ \ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 bottom-group\cf2 \strokec2 ">\ <\cf4 \strokec4 span \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 bottom-label\cf2 \strokec2 ">Invert\ <\cf4 \strokec4 button \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 invertOffBtn\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 toggle-btn active\cf2 \strokec2 ">Off\ <\cf4 \strokec4 button \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 invertOnBtn\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 toggle-btn\cf2 \strokec2 ">On\ \ <\cf4 \strokec4 button \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 add-screen-btn\cf2 \strokec2 "\cf4 \strokec4 \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 addScreenBtn\cf2 \strokec2 ">+ Add Screen\ \ \ <\cf4 \strokec4 div \cf5 \strokec5 id\cf2 \strokec2 ="\cf6 \strokec6 screensContainer\cf2 \strokec2 ">\ \ <\cf4 \strokec4 div \cf5 \strokec5 class\cf2 \strokec2 ="\cf6 \strokec6 panel-bottom-bar\cf2 \strokec2 ">\ \ \ \ \ <\cf4 \strokec4 script\cf2 \strokec2 >\ \cf8 \strokec8 const\cf2 \strokec2 \cf5 \strokec5 COLS\cf2 \strokec2 \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 15\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 \cf5 \strokec5 ROWS\cf2 \strokec2 \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 7\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 \cf5 \strokec5 CHARSET\cf2 \strokec2 \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 " ABCDEFGHIJKLMNOPQRSTUVWXYZ-\'960123456789!?'.,+\'b0%/"\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 displayEl \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "display"\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 appEl \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "app"\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 screensContainer \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "screensContainer"\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 addScreenBtn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "addScreenBtn"\cf2 \strokec2 );\ \ \cf8 \strokec8 const\cf2 \strokec2 fontCleanBtn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "fontCleanBtn"\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 fontRetroBtn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "fontRetroBtn"\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 invertOffBtn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "invertOffBtn"\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 invertOnBtn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "invertOnBtn"\cf2 \strokec2 );\ \ \cf8 \strokec8 const\cf2 \strokec2 grid \cf7 \strokec7 =\cf2 \strokec2 [];\ \cf8 \strokec8 let\cf2 \strokec2 screens \cf7 \strokec7 =\cf2 \strokec2 [];\ \cf8 \strokec8 let\cf2 \strokec2 currentScreenIndex \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf8 \strokec8 let\cf2 \strokec2 cycleInterval \cf7 \strokec7 =\cf2 \strokec2 \cf8 \strokec8 null\cf2 \strokec2 ;\ \cf8 \strokec8 let\cf2 \strokec2 isFullscreen \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 false\cf2 \strokec2 ;\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 createCell\cf2 \strokec2 () \{\ \cf8 \strokec8 const\cf2 \strokec2 flap \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ flap.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "flap"\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 topHalf \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ topHalf.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "half top"\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 topSpan \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "span"\cf2 \strokec2 );\ topSpan.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "char"\cf2 \strokec2 ;\ topSpan.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 ;\ topHalf.\cf7 \strokec7 appendChild\cf2 \strokec2 (topSpan);\ \ \cf8 \strokec8 const\cf2 \strokec2 bottomHalf \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ bottomHalf.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "half bottom"\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 bottomSpan \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "span"\cf2 \strokec2 );\ bottomSpan.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "char"\cf2 \strokec2 ;\ bottomSpan.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 ;\ bottomHalf.\cf7 \strokec7 appendChild\cf2 \strokec2 (bottomSpan);\ \ flap.\cf7 \strokec7 appendChild\cf2 \strokec2 (topHalf);\ flap.\cf7 \strokec7 appendChild\cf2 \strokec2 (bottomHalf);\ \ \cf8 \strokec8 return\cf2 \strokec2 \{\ \cf4 \strokec4 el\cf7 \strokec7 :\cf2 \strokec2 flap,\ \cf4 \strokec4 current\cf7 \strokec7 :\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 ,\ topHalf,\ bottomHalf,\ topSpan,\ bottomSpan\ \};\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 buildDisplay\cf2 \strokec2 () \{\ displayEl.innerHTML \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 ""\cf2 \strokec2 ;\ grid.length \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ;\ \ \cf8 \strokec8 for\cf2 \strokec2 (\cf8 \strokec8 let\cf2 \strokec2 r \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ; r \cf7 \strokec7 <\cf2 \strokec2 \cf5 \strokec5 ROWS\cf2 \strokec2 ; r\cf7 \strokec7 ++\cf2 \strokec2 ) \{\ \cf8 \strokec8 const\cf2 \strokec2 rowEl \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ rowEl.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "row"\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 rowCells \cf7 \strokec7 =\cf2 \strokec2 [];\ \cf8 \strokec8 for\cf2 \strokec2 (\cf8 \strokec8 let\cf2 \strokec2 c \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ; c \cf7 \strokec7 <\cf2 \strokec2 \cf5 \strokec5 COLS\cf2 \strokec2 ; c\cf7 \strokec7 ++\cf2 \strokec2 ) \{\ \cf8 \strokec8 const\cf2 \strokec2 cell \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 createCell\cf2 \strokec2 ();\ rowEl.\cf7 \strokec7 appendChild\cf2 \strokec2 (cell.el);\ rowCells.\cf7 \strokec7 push\cf2 \strokec2 (cell);\ \}\ displayEl.\cf7 \strokec7 appendChild\cf2 \strokec2 (rowEl);\ grid.\cf7 \strokec7 push\cf2 \strokec2 (rowCells);\ \}\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 textToLines\cf2 \strokec2 (text) \{\ \cf8 \strokec8 const\cf2 \strokec2 maxCols \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 COLS\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 maxRows \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 ROWS\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 words \cf7 \strokec7 =\cf2 \strokec2 (text \cf7 \strokec7 ||\cf2 \strokec2 \cf6 \strokec6 ""\cf2 \strokec2 ).\cf7 \strokec7 split\cf2 \strokec2 (\cf6 \strokec6 /\\s+/\cf2 \strokec2 ).\cf7 \strokec7 filter\cf2 \strokec2 (\cf5 \strokec5 Boolean\cf2 \strokec2 );\ \ \cf8 \strokec8 const\cf2 \strokec2 lines \cf7 \strokec7 =\cf2 \strokec2 [];\ \cf8 \strokec8 let\cf2 \strokec2 current \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 ""\cf2 \strokec2 ;\ \ \cf8 \strokec8 for\cf2 \strokec2 (\cf8 \strokec8 const\cf2 \strokec2 w \cf8 \strokec8 of\cf2 \strokec2 words) \{\ \cf8 \strokec8 if\cf2 \strokec2 (\cf7 \strokec7 !\cf2 \strokec2 current.length) \{\ current \cf7 \strokec7 =\cf2 \strokec2 w;\ \} \cf8 \strokec8 else\cf2 \strokec2 \cf8 \strokec8 if\cf2 \strokec2 ((current \cf7 \strokec7 +\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 \cf7 \strokec7 +\cf2 \strokec2 w).length \cf7 \strokec7 <=\cf2 \strokec2 maxCols) \{\ current \cf7 \strokec7 +=\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 \cf7 \strokec7 +\cf2 \strokec2 w;\ \} \cf8 \strokec8 else\cf2 \strokec2 \{\ lines.\cf7 \strokec7 push\cf2 \strokec2 (current.\cf7 \strokec7 slice\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 , maxCols));\ \cf8 \strokec8 if\cf2 \strokec2 (lines.length \cf7 \strokec7 >=\cf2 \strokec2 maxRows) \cf8 \strokec8 break\cf2 \strokec2 ;\ current \cf7 \strokec7 =\cf2 \strokec2 w;\ \}\ \}\ \ \cf8 \strokec8 if\cf2 \strokec2 (lines.length \cf7 \strokec7 <\cf2 \strokec2 maxRows \cf7 \strokec7 &&\cf2 \strokec2 current.length) \{\ lines.\cf7 \strokec7 push\cf2 \strokec2 (current.\cf7 \strokec7 slice\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 , maxCols));\ \}\ \ \f1\i \cf9 \strokec9 // Center horizontally \f0\i0 \cf2 \strokec2 \ \cf8 \strokec8 const\cf2 \strokec2 centeredLines \cf7 \strokec7 =\cf2 \strokec2 lines.\cf7 \strokec7 map\cf2 \strokec2 ((ln) \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf8 \strokec8 const\cf2 \strokec2 trimmed \cf7 \strokec7 =\cf2 \strokec2 ln.\cf7 \strokec7 trim\cf2 \strokec2 ();\ \cf8 \strokec8 if\cf2 \strokec2 (trimmed.length \cf7 \strokec7 ===\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ) \cf8 \strokec8 return\cf2 \strokec2 \cf6 \strokec6 ""\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 padding \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 Math\cf2 \strokec2 .\cf7 \strokec7 floor\cf2 \strokec2 ((maxCols \cf7 \strokec7 -\cf2 \strokec2 trimmed.length) \cf7 \strokec7 /\cf2 \strokec2 \cf5 \strokec5 2\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 line \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 .\cf7 \strokec7 repeat\cf2 \strokec2 (padding) \cf7 \strokec7 +\cf2 \strokec2 trimmed;\ \cf8 \strokec8 return\cf2 \strokec2 line.\cf7 \strokec7 padEnd\cf2 \strokec2 (maxCols, \cf6 \strokec6 " "\cf2 \strokec2 ).\cf7 \strokec7 slice\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 , maxCols);\ \});\ \ \f1\i \cf9 \strokec9 // Center vertically \f0\i0 \cf2 \strokec2 \ \cf8 \strokec8 const\cf2 \strokec2 topPadding \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 Math\cf2 \strokec2 .\cf7 \strokec7 floor\cf2 \strokec2 ((maxRows \cf7 \strokec7 -\cf2 \strokec2 centeredLines.length) \cf7 \strokec7 /\cf2 \strokec2 \cf5 \strokec5 2\cf2 \strokec2 );\ \cf8 \strokec8 const\cf2 \strokec2 result \cf7 \strokec7 =\cf2 \strokec2 [];\ \cf8 \strokec8 for\cf2 \strokec2 (\cf8 \strokec8 let\cf2 \strokec2 i \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ; i \cf7 \strokec7 <\cf2 \strokec2 topPadding; i\cf7 \strokec7 ++\cf2 \strokec2 ) \{\ result.\cf7 \strokec7 push\cf2 \strokec2 (\cf6 \strokec6 ""\cf2 \strokec2 );\ \}\ result.\cf7 \strokec7 push\cf2 \strokec2 (\cf7 \strokec7 ...\cf2 \strokec2 centeredLines);\ \cf8 \strokec8 while\cf2 \strokec2 (result.length \cf7 \strokec7 <\cf2 \strokec2 maxRows) \{\ result.\cf7 \strokec7 push\cf2 \strokec2 (\cf6 \strokec6 ""\cf2 \strokec2 );\ \}\ \ \cf8 \strokec8 return\cf2 \strokec2 result;\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 cycleLetter\cf2 \strokec2 (cell, targetChar) \{\ \cf8 \strokec8 if\cf2 \strokec2 (cell.current \cf7 \strokec7 ===\cf2 \strokec2 targetChar) \cf8 \strokec8 return\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 \{ topHalf, bottomHalf, topSpan, bottomSpan \} \cf7 \strokec7 =\cf2 \strokec2 cell;\ \cf8 \strokec8 let\cf2 \strokec2 currentIndex \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 Math\cf2 \strokec2 .\cf7 \strokec7 max\cf2 \strokec2 (\cf5 \strokec5 0\cf2 \strokec2 , \cf5 \strokec5 CHARSET\cf2 \strokec2 .\cf7 \strokec7 indexOf\cf2 \strokec2 (cell.current));\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 flipToNextLetter\cf2 \strokec2 () \{\ \cf8 \strokec8 if\cf2 \strokec2 (\cf5 \strokec5 CHARSET\cf2 \strokec2 [currentIndex] \cf7 \strokec7 ===\cf2 \strokec2 targetChar) \{\ topSpan.innerText \cf7 \strokec7 =\cf2 \strokec2 bottomSpan.innerText \cf7 \strokec7 =\cf2 \strokec2 targetChar;\ cell.current \cf7 \strokec7 =\cf2 \strokec2 targetChar;\ \cf8 \strokec8 return\cf2 \strokec2 ;\ \}\ \ \cf8 \strokec8 const\cf2 \strokec2 nextLetter \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 CHARSET\cf2 \strokec2 [currentIndex];\ \cf8 \strokec8 const\cf2 \strokec2 nextIndex \cf7 \strokec7 =\cf2 \strokec2 (currentIndex \cf7 \strokec7 +\cf2 \strokec2 \cf5 \strokec5 1\cf2 \strokec2 ) \cf7 \strokec7 %\cf2 \strokec2 \cf5 \strokec5 CHARSET\cf2 \strokec2 .length;\ \cf8 \strokec8 const\cf2 \strokec2 upcomingLetter \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 CHARSET\cf2 \strokec2 [nextIndex];\ \ topSpan.innerText \cf7 \strokec7 =\cf2 \strokec2 nextLetter;\ bottomSpan.innerText \cf7 \strokec7 =\cf2 \strokec2 nextLetter;\ \ topHalf.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "flip-top"\cf2 \strokec2 );\ \ \cf7 \strokec7 setTimeout\cf2 \strokec2 (() \cf7 \strokec7 =>\cf2 \strokec2 \{\ topHalf.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "flip-top"\cf2 \strokec2 );\ bottomSpan.innerText \cf7 \strokec7 =\cf2 \strokec2 upcomingLetter;\ bottomHalf.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "flip-bottom"\cf2 \strokec2 );\ \ \cf7 \strokec7 setTimeout\cf2 \strokec2 (() \cf7 \strokec7 =>\cf2 \strokec2 \{\ bottomHalf.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "flip-bottom"\cf2 \strokec2 );\ topSpan.innerText \cf7 \strokec7 =\cf2 \strokec2 upcomingLetter;\ currentIndex \cf7 \strokec7 =\cf2 \strokec2 nextIndex;\ \cf7 \strokec7 flipToNextLetter\cf2 \strokec2 ();\ \}, \cf5 \strokec5 40\cf2 \strokec2 );\ \}, \cf5 \strokec5 70\cf2 \strokec2 );\ \}\ \ \cf7 \strokec7 flipToNextLetter\cf2 \strokec2 ();\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 setDisplayFromText\cf2 \strokec2 (raw) \{\ \cf8 \strokec8 const\cf2 \strokec2 upper \cf7 \strokec7 =\cf2 \strokec2 (raw \cf7 \strokec7 ||\cf2 \strokec2 \cf6 \strokec6 ""\cf2 \strokec2 ).\cf7 \strokec7 toUpperCase\cf2 \strokec2 ();\ \cf8 \strokec8 const\cf2 \strokec2 lines \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 textToLines\cf2 \strokec2 (upper);\ \ \cf8 \strokec8 for\cf2 \strokec2 (\cf8 \strokec8 let\cf2 \strokec2 r \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ; r \cf7 \strokec7 <\cf2 \strokec2 \cf5 \strokec5 ROWS\cf2 \strokec2 ; r\cf7 \strokec7 ++\cf2 \strokec2 ) \{\ \cf8 \strokec8 const\cf2 \strokec2 line \cf7 \strokec7 =\cf2 \strokec2 lines[r];\ \cf8 \strokec8 for\cf2 \strokec2 (\cf8 \strokec8 let\cf2 \strokec2 c \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ; c \cf7 \strokec7 <\cf2 \strokec2 \cf5 \strokec5 COLS\cf2 \strokec2 ; c\cf7 \strokec7 ++\cf2 \strokec2 ) \{\ \cf8 \strokec8 const\cf2 \strokec2 ch \cf7 \strokec7 =\cf2 \strokec2 line[c] \cf7 \strokec7 ||\cf2 \strokec2 \cf6 \strokec6 " "\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 cell \cf7 \strokec7 =\cf2 \strokec2 grid[r][c];\ \cf7 \strokec7 cycleLetter\cf2 \strokec2 (cell, ch);\ \}\ \}\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 createScreenCard\cf2 \strokec2 (index) \{\ \cf8 \strokec8 const\cf2 \strokec2 card \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ \ \cf8 \strokec8 const\cf2 \strokec2 label \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ label.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "screen-label"\cf2 \strokec2 ;\ label.textContent \cf7 \strokec7 =\cf2 \strokec2 `\cf6 \strokec6 Screen \cf2 \strokec2 $\{index + 1\}`;\ card.\cf7 \strokec7 appendChild\cf2 \strokec2 (label);\ \ \cf8 \strokec8 const\cf2 \strokec2 screenCard \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ screenCard.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "screen-card"\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 textWrapper \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ textWrapper.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "screen-text-wrapper"\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 input \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "textarea"\cf2 \strokec2 );\ input.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "text-input"\cf2 \strokec2 ;\ input.autocomplete \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "off"\cf2 \strokec2 ;\ input.spellcheck \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 false\cf2 \strokec2 ;\ \ textWrapper.\cf7 \strokec7 appendChild\cf2 \strokec2 (input);\ \ \cf8 \strokec8 const\cf2 \strokec2 underline \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ underline.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "underline"\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 footer \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ footer.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "screen-footer"\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 durationWrap \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ durationWrap.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "duration-input-wrap"\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 clockIcon \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "div"\cf2 \strokec2 );\ clockIcon.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "clock-icon"\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 durationInput \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "input"\cf2 \strokec2 );\ durationInput.type \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "number"\cf2 \strokec2 ;\ durationInput.value \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "10"\cf2 \strokec2 ;\ durationInput.min \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "1"\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 durationUnit \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "span"\cf2 \strokec2 );\ durationUnit.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 " s"\cf2 \strokec2 ;\ durationWrap.\cf7 \strokec7 appendChild\cf2 \strokec2 (clockIcon);\ durationWrap.\cf7 \strokec7 appendChild\cf2 \strokec2 (durationInput);\ durationWrap.\cf7 \strokec7 appendChild\cf2 \strokec2 (durationUnit);\ \ \cf8 \strokec8 const\cf2 \strokec2 removeBtn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 createElement\cf2 \strokec2 (\cf6 \strokec6 "button"\cf2 \strokec2 );\ removeBtn.className \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "remove-btn"\cf2 \strokec2 ;\ removeBtn.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "Remove"\cf2 \strokec2 ;\ removeBtn.onclick \cf7 \strokec7 =\cf2 \strokec2 () \cf7 \strokec7 =>\cf2 \strokec2 \cf7 \strokec7 removeScreen\cf2 \strokec2 (index);\ \ footer.\cf7 \strokec7 appendChild\cf2 \strokec2 (durationWrap);\ footer.\cf7 \strokec7 appendChild\cf2 \strokec2 (removeBtn);\ \ screenCard.\cf7 \strokec7 appendChild\cf2 \strokec2 (textWrapper);\ screenCard.\cf7 \strokec7 appendChild\cf2 \strokec2 (underline);\ screenCard.\cf7 \strokec7 appendChild\cf2 \strokec2 (footer);\ \ card.\cf7 \strokec7 appendChild\cf2 \strokec2 (screenCard);\ \ input.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "input"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf8 \strokec8 const\cf2 \strokec2 cursorPos \cf7 \strokec7 =\cf2 \strokec2 input.selectionStart;\ \cf8 \strokec8 let\cf2 \strokec2 value \cf7 \strokec7 =\cf2 \strokec2 input.value.\cf7 \strokec7 toUpperCase\cf2 \strokec2 ();\ input.value \cf7 \strokec7 =\cf2 \strokec2 value;\ input.\cf7 \strokec7 setSelectionRange\cf2 \strokec2 (cursorPos, cursorPos);\ \cf8 \strokec8 if\cf2 \strokec2 (currentScreenIndex \cf7 \strokec7 ===\cf2 \strokec2 index) \{\ \cf7 \strokec7 setDisplayFromText\cf2 \strokec2 (value);\ \}\ \});\ \ durationInput.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "change"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf7 \strokec7 updateCycle\cf2 \strokec2 ();\ \});\ \ screensContainer.\cf7 \strokec7 appendChild\cf2 \strokec2 (card);\ \ \cf8 \strokec8 return\cf2 \strokec2 \{\ \cf4 \strokec4 element\cf7 \strokec7 :\cf2 \strokec2 card,\ input,\ durationInput\ \};\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 addScreen\cf2 \strokec2 () \{\ \cf8 \strokec8 const\cf2 \strokec2 screen \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 createScreenCard\cf2 \strokec2 (screens.length);\ screens.\cf7 \strokec7 push\cf2 \strokec2 (screen);\ \ \cf8 \strokec8 if\cf2 \strokec2 (screens.length \cf7 \strokec7 ===\cf2 \strokec2 \cf5 \strokec5 1\cf2 \strokec2 ) \{\ screen.input.value \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "FLAPPI"\cf2 \strokec2 ;\ screen.durationInput.value \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "10"\cf2 \strokec2 ;\ screen.input.\cf7 \strokec7 dispatchEvent\cf2 \strokec2 (\cf8 \strokec8 new\cf2 \strokec2 \cf5 \strokec5 Event\cf2 \strokec2 (\cf6 \strokec6 "input"\cf2 \strokec2 ));\ screen.input.\cf7 \strokec7 focus\cf2 \strokec2 ();\ \} \cf8 \strokec8 else\cf2 \strokec2 \cf8 \strokec8 if\cf2 \strokec2 (screens.length \cf7 \strokec7 ===\cf2 \strokec2 \cf5 \strokec5 2\cf2 \strokec2 ) \{\ screen.input.value \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "I HAVE NOT FAILED. I'VE JUST FOUND 10,000 WAYS THAT WON'T WORK \'96 THOMAS EDISON"\cf2 \strokec2 ;\ screen.durationInput.value \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "10"\cf2 \strokec2 ;\ screen.input.\cf7 \strokec7 dispatchEvent\cf2 \strokec2 (\cf8 \strokec8 new\cf2 \strokec2 \cf5 \strokec5 Event\cf2 \strokec2 (\cf6 \strokec6 "input"\cf2 \strokec2 ));\ \}\ \ \cf7 \strokec7 updateCycle\cf2 \strokec2 ();\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 toggleFullscreen\cf2 \strokec2 () \{\ isFullscreen \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 !\cf2 \strokec2 isFullscreen;\ appEl.classList.\cf7 \strokec7 toggle\cf2 \strokec2 (\cf6 \strokec6 "fullscreen"\cf2 \strokec2 , isFullscreen);\ \ \cf8 \strokec8 const\cf2 \strokec2 btn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "fullscreenBtn"\cf2 \strokec2 );\ \cf8 \strokec8 if\cf2 \strokec2 (isFullscreen) \{\ btn.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "Exit Fullscreen"\cf2 \strokec2 ;\ \cf7 \strokec7 document\cf2 \strokec2 .body.style.overflow \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "hidden"\cf2 \strokec2 ;\ \} \cf8 \strokec8 else\cf2 \strokec2 \{\ btn.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "Fullscreen"\cf2 \strokec2 ;\ \cf7 \strokec7 document\cf2 \strokec2 .body.style.overflow \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "auto"\cf2 \strokec2 ;\ \}\ \}\ \ \cf8 \strokec8 let\cf2 \strokec2 googleCalendarToken \cf7 \strokec7 =\cf2 \strokec2 \cf8 \strokec8 null\cf2 \strokec2 ;\ \ \f1\i \cf9 \strokec9 // Google Calendar integration \f0\i0 \cf2 \strokec2 \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 initGoogleCalendar\cf2 \strokec2 () \{\ \cf8 \strokec8 const\cf2 \strokec2 clientId \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com'\cf2 \strokec2 ;\ \cf8 \strokec8 const\cf2 \strokec2 redirectUri \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 window\cf2 \strokec2 .location.origin \cf7 \strokec7 +\cf2 \strokec2 \cf7 \strokec7 window\cf2 \strokec2 .location.pathname;\ \cf8 \strokec8 const\cf2 \strokec2 scope \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 'https://www.googleapis.com/auth/calendar.readonly'\cf2 \strokec2 ;\ \ \cf8 \strokec8 const\cf2 \strokec2 params \cf7 \strokec7 =\cf2 \strokec2 \cf8 \strokec8 new\cf2 \strokec2 \cf5 \strokec5 URLSearchParams\cf2 \strokec2 (\cf7 \strokec7 window\cf2 \strokec2 .location.search);\ \cf8 \strokec8 const\cf2 \strokec2 code \cf7 \strokec7 =\cf2 \strokec2 params.\cf7 \strokec7 get\cf2 \strokec2 (\cf6 \strokec6 'code'\cf2 \strokec2 );\ \ \cf8 \strokec8 if\cf2 \strokec2 (code \cf7 \strokec7 &&\cf2 \strokec2 \cf7 \strokec7 !\cf2 \strokec2 googleCalendarToken) \{\ \cf7 \strokec7 localStorage\cf2 \strokec2 .\cf7 \strokec7 setItem\cf2 \strokec2 (\cf6 \strokec6 'google_code'\cf2 \strokec2 , code);\ \cf7 \strokec7 window\cf2 \strokec2 .history.\cf7 \strokec7 replaceState\cf2 \strokec2 (\{\}, \cf7 \strokec7 document\cf2 \strokec2 .title, \cf7 \strokec7 window\cf2 \strokec2 .location.pathname);\ \}\ \ \f1\i \cf9 \strokec9 // Check for stored token \f0\i0 \cf2 \strokec2 \ \cf8 \strokec8 const\cf2 \strokec2 storedToken \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 localStorage\cf2 \strokec2 .\cf7 \strokec7 getItem\cf2 \strokec2 (\cf6 \strokec6 'google_access_token'\cf2 \strokec2 );\ \cf8 \strokec8 if\cf2 \strokec2 (storedToken) \{\ googleCalendarToken \cf7 \strokec7 =\cf2 \strokec2 storedToken;\ \cf7 \strokec7 getGoogleCalendarEvents\cf2 \strokec2 ();\ \}\ \}\ \ \cf8 \strokec8 async\cf2 \strokec2 \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 getGoogleCalendarEvents\cf2 \strokec2 () \{\ \cf8 \strokec8 if\cf2 \strokec2 (\cf7 \strokec7 !\cf2 \strokec2 googleCalendarToken) \cf8 \strokec8 return\cf2 \strokec2 ;\ \ \cf8 \strokec8 try\cf2 \strokec2 \{\ \cf8 \strokec8 const\cf2 \strokec2 now \cf7 \strokec7 =\cf2 \strokec2 \cf8 \strokec8 new\cf2 \strokec2 \cf5 \strokec5 Date\cf2 \strokec2 ();\ \cf8 \strokec8 const\cf2 \strokec2 response \cf7 \strokec7 =\cf2 \strokec2 \cf8 \strokec8 await\cf2 \strokec2 \cf7 \strokec7 fetch\cf2 \strokec2 (\ `\cf6 \strokec6 https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=\cf2 \strokec2 $\{now.toISOString()\}\cf6 \strokec6 &maxResults=1&singleEvents=true&orderBy=startTime\cf2 \strokec2 `,\ \{\ \cf4 \strokec4 headers\cf7 \strokec7 :\cf2 \strokec2 \{\ \cf4 \strokec4 'Authorization'\cf7 \strokec7 :\cf2 \strokec2 `\cf6 \strokec6 Bearer \cf2 \strokec2 $\{googleCalendarToken\}`\ \}\ \}\ );\ \ \cf8 \strokec8 if\cf2 \strokec2 (response.ok) \{\ \cf8 \strokec8 const\cf2 \strokec2 data \cf7 \strokec7 =\cf2 \strokec2 \cf8 \strokec8 await\cf2 \strokec2 response.\cf7 \strokec7 json\cf2 \strokec2 ();\ \cf8 \strokec8 if\cf2 \strokec2 (data.items \cf7 \strokec7 &&\cf2 \strokec2 data.items.length \cf7 \strokec7 >\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ) \{\ \cf8 \strokec8 const\cf2 \strokec2 event \cf7 \strokec7 =\cf2 \strokec2 data.items[\cf5 \strokec5 0\cf2 \strokec2 ];\ \cf8 \strokec8 const\cf2 \strokec2 eventTime \cf7 \strokec7 =\cf2 \strokec2 event.start.dateTime \cf7 \strokec7 ||\cf2 \strokec2 event.start.date;\ \cf8 \strokec8 const\cf2 \strokec2 eventInfo \cf7 \strokec7 =\cf2 \strokec2 `$\{event.summary\}\cf6 \strokec6 at \cf2 \strokec2 $\{new Date(eventTime).toLocaleTimeString()\}`;\ \ \f1\i \cf9 \strokec9 // Check if we have a Screen 4, if not create it \f0\i0 \cf2 \strokec2 \ \cf8 \strokec8 while\cf2 \strokec2 (screens.length \cf7 \strokec7 <\cf2 \strokec2 \cf5 \strokec5 4\cf2 \strokec2 ) \{\ \cf7 \strokec7 addScreen\cf2 \strokec2 ();\ \}\ \ \f1\i \cf9 \strokec9 // Update Screen 4 with calendar info \f0\i0 \cf2 \strokec2 \ screens[\cf5 \strokec5 3\cf2 \strokec2 ].input.value \cf7 \strokec7 =\cf2 \strokec2 eventInfo;\ screens[\cf5 \strokec5 3\cf2 \strokec2 ].input.\cf7 \strokec7 dispatchEvent\cf2 \strokec2 (\cf8 \strokec8 new\cf2 \strokec2 \cf5 \strokec5 Event\cf2 \strokec2 (\cf6 \strokec6 "input"\cf2 \strokec2 ));\ \}\ \}\ \} \cf8 \strokec8 catch\cf2 \strokec2 (err) \{\ \cf5 \strokec5 console\cf2 \strokec2 .\cf7 \strokec7 error\cf2 \strokec2 (\cf6 \strokec6 'Calendar error:'\cf2 \strokec2 , err);\ \}\ \}\ \ \f1\i \cf9 \strokec9 // Poll calendar every 30 seconds \f0\i0 \cf2 \strokec2 \ \cf7 \strokec7 setInterval\cf2 \strokec2 (() \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf8 \strokec8 if\cf2 \strokec2 (googleCalendarToken) \{\ \cf7 \strokec7 getGoogleCalendarEvents\cf2 \strokec2 ();\ \}\ \}, \cf5 \strokec5 30000\cf2 \strokec2 );\ \ \cf7 \strokec7 initGoogleCalendar\cf2 \strokec2 ();\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 removeScreen\cf2 \strokec2 (index) \{\ \cf8 \strokec8 if\cf2 \strokec2 (screens.length \cf7 \strokec7 ===\cf2 \strokec2 \cf5 \strokec5 1\cf2 \strokec2 ) \{\ \cf7 \strokec7 alert\cf2 \strokec2 (\cf6 \strokec6 "You must have at least one screen"\cf2 \strokec2 );\ \cf8 \strokec8 return\cf2 \strokec2 ;\ \}\ screens[index].element.\cf7 \strokec7 remove\cf2 \strokec2 ();\ screens.\cf7 \strokec7 splice\cf2 \strokec2 (index, \cf5 \strokec5 1\cf2 \strokec2 );\ screens.\cf7 \strokec7 forEach\cf2 \strokec2 ((s, i) \cf7 \strokec7 =>\cf2 \strokec2 \{\ s.element.\cf7 \strokec7 querySelector\cf2 \strokec2 (\cf6 \strokec6 ".screen-label"\cf2 \strokec2 ).textContent \cf7 \strokec7 =\cf2 \strokec2 `\cf6 \strokec6 Screen \cf2 \strokec2 $\{i + 1\}`;\ \});\ \cf8 \strokec8 if\cf2 \strokec2 (currentScreenIndex \cf7 \strokec7 >=\cf2 \strokec2 screens.length) \{\ currentScreenIndex \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ;\ \}\ \cf7 \strokec7 updateCycle\cf2 \strokec2 ();\ \cf8 \strokec8 if\cf2 \strokec2 (screens.length \cf7 \strokec7 >\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ) \{\ \cf7 \strokec7 setDisplayFromText\cf2 \strokec2 (screens[currentScreenIndex].input.value);\ \}\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 updateCycle\cf2 \strokec2 () \{\ \cf8 \strokec8 if\cf2 \strokec2 (cycleInterval) \cf7 \strokec7 clearInterval\cf2 \strokec2 (cycleInterval);\ \ \cf8 \strokec8 if\cf2 \strokec2 (screens.length \cf7 \strokec7 ===\cf2 \strokec2 \cf5 \strokec5 1\cf2 \strokec2 ) \{\ currentScreenIndex \cf7 \strokec7 =\cf2 \strokec2 \cf5 \strokec5 0\cf2 \strokec2 ;\ \cf8 \strokec8 return\cf2 \strokec2 ;\ \}\ \ \cf8 \strokec8 const\cf2 \strokec2 duration \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 parseInt\cf2 \strokec2 (screens[currentScreenIndex].durationInput.value) \cf7 \strokec7 *\cf2 \strokec2 \cf5 \strokec5 1000\cf2 \strokec2 ;\ cycleInterval \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 setInterval\cf2 \strokec2 (() \cf7 \strokec7 =>\cf2 \strokec2 \{\ currentScreenIndex \cf7 \strokec7 =\cf2 \strokec2 (currentScreenIndex \cf7 \strokec7 +\cf2 \strokec2 \cf5 \strokec5 1\cf2 \strokec2 ) \cf7 \strokec7 %\cf2 \strokec2 screens.length;\ \cf7 \strokec7 setDisplayFromText\cf2 \strokec2 (screens[currentScreenIndex].input.value);\ \}, duration);\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 setFontMode\cf2 \strokec2 (mode) \{\ \cf8 \strokec8 if\cf2 \strokec2 (mode \cf7 \strokec7 ===\cf2 \strokec2 \cf6 \strokec6 "clean"\cf2 \strokec2 ) \{\ appEl.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "font-retro"\cf2 \strokec2 );\ appEl.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "font-clean"\cf2 \strokec2 );\ fontCleanBtn.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ fontRetroBtn.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ \} \cf8 \strokec8 else\cf2 \strokec2 \{\ appEl.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "font-clean"\cf2 \strokec2 );\ appEl.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "font-retro"\cf2 \strokec2 );\ fontRetroBtn.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ fontCleanBtn.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ \}\ \}\ \ \cf8 \strokec8 function\cf2 \strokec2 \cf7 \strokec7 setInvert\cf2 \strokec2 (on) \{\ \cf8 \strokec8 if\cf2 \strokec2 (on) \{\ appEl.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "invert"\cf2 \strokec2 );\ invertOnBtn.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ invertOffBtn.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ \} \cf8 \strokec8 else\cf2 \strokec2 \{\ appEl.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "invert"\cf2 \strokec2 );\ invertOffBtn.classList.\cf7 \strokec7 add\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ invertOnBtn.classList.\cf7 \strokec7 remove\cf2 \strokec2 (\cf6 \strokec6 "active"\cf2 \strokec2 );\ \}\ \}\ \ fontCleanBtn.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "click"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \cf7 \strokec7 setFontMode\cf2 \strokec2 (\cf6 \strokec6 "clean"\cf2 \strokec2 ));\ fontRetroBtn.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "click"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \cf7 \strokec7 setFontMode\cf2 \strokec2 (\cf6 \strokec6 "retro"\cf2 \strokec2 ));\ invertOffBtn.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "click"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \cf7 \strokec7 setInvert\cf2 \strokec2 (\cf5 \strokec5 false\cf2 \strokec2 ));\ invertOnBtn.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "click"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \cf7 \strokec7 setInvert\cf2 \strokec2 (\cf5 \strokec5 true\cf2 \strokec2 ));\ addScreenBtn.\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "click"\cf2 \strokec2 , addScreen);\ \ \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "fullscreenBtn"\cf2 \strokec2 ).\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "click"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf8 \strokec8 const\cf2 \strokec2 displayWrapper \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 querySelector\cf2 \strokec2 (\cf6 \strokec6 ".display-wrapper"\cf2 \strokec2 );\ \ \cf8 \strokec8 if\cf2 \strokec2 (\cf7 \strokec7 !document\cf2 \strokec2 .fullscreenElement) \{\ displayWrapper.\cf7 \strokec7 requestFullscreen\cf2 \strokec2 ().\cf8 \strokec8 catch\cf2 \strokec2 (err \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf5 \strokec5 console\cf2 \strokec2 .\cf7 \strokec7 error\cf2 \strokec2 (`\cf6 \strokec6 Error attempting to enable fullscreen: \cf2 \strokec2 $\{err.message\}`);\ \});\ \} \cf8 \strokec8 else\cf2 \strokec2 \{\ \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 exitFullscreen\cf2 \strokec2 ();\ \}\ \});\ \ \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 addEventListener\cf2 \strokec2 (\cf6 \strokec6 "fullscreenchange"\cf2 \strokec2 , () \cf7 \strokec7 =>\cf2 \strokec2 \{\ \cf8 \strokec8 const\cf2 \strokec2 btn \cf7 \strokec7 =\cf2 \strokec2 \cf7 \strokec7 document\cf2 \strokec2 .\cf7 \strokec7 getElementById\cf2 \strokec2 (\cf6 \strokec6 "fullscreenBtn"\cf2 \strokec2 );\ \cf8 \strokec8 if\cf2 \strokec2 (\cf7 \strokec7 document\cf2 \strokec2 .fullscreenElement) \{\ btn.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "Exit Fullscreen"\cf2 \strokec2 ;\ \} \cf8 \strokec8 else\cf2 \strokec2 \{\ btn.textContent \cf7 \strokec7 =\cf2 \strokec2 \cf6 \strokec6 "Fullscreen"\cf2 \strokec2 ;\ \}\ \});\ \ \cf7 \strokec7 buildDisplay\cf2 \strokec2 ();\ \cf7 \strokec7 addScreen\cf2 \strokec2 ();\ \cf7 \strokec7 addScreen\cf2 \strokec2 ();\ \ \ }