diff --git a/ReadMe.md b/ReadMe.md index f543aec..3a63402 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -2,11 +2,29 @@ This is a web-app for a license-plate word game. This was built with the [Aurelia](https://aurelia.io/) application framework. -_The server is under development and is not open source._ Here is a [development deployment](http://radiant-hamlet-54079.herokuapp.com/). This server may be sleeping, in which case it will take 20 seconds to restart. +## Install and Build + +You must have node.js v14+ installed. +Then use git to get a copy of this repo, +and install and build in the normal way... +``` +npm install +npm run build +``` + +You may run the dummy-server locally so you can work with the web-app. +``` +npm run start-server +``` +_The actual game server is under development and is not open source._ +Note that the dummy-server only provides data of the proper type for a given contect, but it doesn't actually provide answers. + +## Overview + This video shows an example puzzle session: https://user-images.githubusercontent.com/940931/160249859-00d26f0b-ba52-48e5-a1b5-80cbb583d4ec.mov @@ -15,13 +33,13 @@ https://user-images.githubusercontent.com/940931/160249859-00d26f0b-ba52-48e5-a1 - Words must contain the original three characters, in the order in which they were given. - Words may consist of only letters. Punctuation is not supported yet. -For example, words such as "don't", "check-in", or "full moon" are not accepted as solutions. +For example, words such as "don't", "check-in", or "full moon" are not accepted as answers. - Words may only be single words, and not compounds. - Words may be up to 15 characters long. Longer words are not supported due to UI contraints. # Game Features -- The server only provides puzzles with known solutions. +- The server only provides puzzles with known answers. - All puzzles are graded for difficulty. - The server provides simple puzzles, until directed by the web-app to provide more difficult ones. - The server is stateless. @@ -37,7 +55,7 @@ Longer words are not supported due to UI contraints. These messages time-out as appropriate. - The user may request a new game, optionally specifying the characters for the puzzle. - The user may request hints. -Each hint randomly shows the pattern for a single known solution. +Each hint randomly shows the pattern for a single known answer. - Recent answer results and hints are displayed in the bottom portion of the license plate, just below the main text input area. These messages time-out as appropriate. - Answers are lised in a separate view displayed over the same license plate image. @@ -57,6 +75,7 @@ These messages time-out as appropriate. - The hamburger menu has inconsistent style. - The New Game Controls should display a completion messgae for a few seconds immediately after a new game is started. - There is no way for the user to contest a word. +- Must add coding style management, such as [TypeScript ESLint](https://typescript-eslint.io/). # Design @@ -90,7 +109,7 @@ graph TB class external,server server class library,http library %% code - click editor "https://github.com/psnider/license-plate-game-aurelia/blob/main/src/LicensePlateSolutionEditorFreeEntry.ts" + click editor "https://github.com/psnider/license-plate-game-aurelia/blob/main/src/LicensePlateAnswerEditorFreeEntry.ts" click current "https://github.com/psnider/license-plate-game-aurelia/blob/main/src/CurrentGameControls.ts" click new "https://github.com/psnider/license-plate-game-aurelia/blob/main/src/StartNewGameControls.ts" click answers_view "https://github.com/psnider/license-plate-game-aurelia/blob/main/src/AnswersPanel.ts" @@ -126,7 +145,7 @@ graph TB ## UI Components for the above Design Diagram - UI Elements Note that the TypeScript is in the sibling file of the same basename. - - [Word Editor](./src/LicensePlateSolutionEditorFreeEntry.html) + - [Word Editor](./src/LicensePlateAnswerEditorFreeEntry.html) - [Current Game Controls](./src/CurrentGameControls.html) - [Start New Game Controls](./src/StartNewGameControls.html) - [Answers Viewer](./src/AnswersPanel.html) @@ -173,3 +192,81 @@ This is the 3rd time I tried Aurelia! Both of the previous times, my project wo - It's easy to confuse Aurelia v1 and v2 documentation. But this is also true of React JS and Vue.js, and probably even worse. Both have a number of complicating revisions and usage models. +# An Aurelia Primer + +I have a few notes about [Aurelia](https://aurelia.io/) here, so you don't have to comb through their documentation just to get started. + +Like other frameworks, Aurelia supports making complex elements for a web-app by combining HTML, CSS, and JavaScript. In this project, each component has one file for HTML, one for JavaScript, and possibly one for CSS. +The components are in the src directory. + +## An Example of a Simple Aurelia Class +One of the simpler components is [InProcessIndicator](./src/InProcessIndicator.html). +It displays an animated busy indicator, used while network requests are active. + +Its HTML consists of an Aurelia-specific _require_ element, which loads the CSS for the component, and a short set of HTML elements: + ```html + + ``` + Each Aurelia component must have a JavaScript class with the name of the class. + For [InProcessIndicator](./src/InProcessIndicator.ts), there's no bound data or any functions, so this is a minimal Aurelia class: + ```typescript + export class InProcessIndicator {} + ``` + Other components can use _InProcessIndicator_ by importing it using the Aurelia-specific _require_ element, and then referencing the component name using the kebab-case form of the name: + ```html + + + ``` + +## Binding Data and Actions to HTML + +- String Interpolation + In [AnswersPanel.html](./src/AnswersPanel.html), the value of the _total_answers_score_ class variable is inserted into HTML text. + ```html +
...for a total score of ${total_answers_score} points.
+ ``` +- Data Binding + In [AnswerRow.html](./src/AnswerRow.html), the value of the _boggle_score_ property of its _current_game_ class variable is bound to the _boggle_score_ property of the contained AnswerScores component by using the Aurelia-specific _bind_ modifier. And similarly for _scrabble_score_. + ```html + + ``` + And the [AnswerScores.ts](./src/AnswerScores.ts) component accepts these data items by using Aurelia-specific _@bindable_ decorators: + ```typescript + export class AnswerScores { + @bindable boggle_score: number + @bindable scrabble_score: number + ``` +- Action Binding + In [Banner.html](./src/Banner.html), its _openAboutPanel()_ function is bound to the click event for a button. + ```HTML + + ``` +- CSS binding + In [GameStatusMessagesSignboard.html](./src/GameStatusMessagesSignboard.html), the value of the _current_css_classes_ class variable is added to the CSS classes for the element, and the value of the _color_style_ class variable is added to the CSS style. + ```html + ${message_text_line} + ``` +- Conditional inclusion of elements + In [AboutPanel.html](./src/AboutPanel.html), the div marked with the Aurelia-specific _if.bind_ property is only added to the component if the _about_panel_is_open_ class variable is true. + ```html +
+ ``` +- Repetition of elements + In [AnswerRow.html](./src/AnswerRow.html), the contents of the div marked with the Aurelia-specific _repeat.for_ property is added once for each entry in its _notes_ class variable. Observe that the syntax of _repeat.for_'s value is: + > variable_scoped_to_HTML of variable_in_class + + Here the note variable is only visible within the contents of the div. + ```html +
+ ${note} +
+ ``` +- State Communication +This web-app uses the Aurelia-specific _EventAggregator_, which is a message service, similar to the Node.js EventEmitter. +This allows communication of state change across arbitrary components, which is very helpful, and which I haven't figured out how to do in either ReactJS or Vue.js. + +Hopefully, these notes will help you read most of the Aurelia specific code in this web-app. + diff --git a/dist/app.2a33eb2b9c39d82e4716.bundle.js b/dist/app.2a33eb2b9c39d82e4716.bundle.js deleted file mode 100644 index 792b670..0000000 --- a/dist/app.2a33eb2b9c39d82e4716.bundle.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkaurelia_app=self.webpackChunkaurelia_app||[]).push([[143],{"AnswerDifficulty.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"\n.grade_level_tag {\n width: max-content;\n font-family: Spinnaker, Arial, sans-serif;\n color: black;\n background-color: #76a76c;\n border: 1px solid #374b33;\n}\n.word_set_size_span_tag {\n width: max-content;\n font-family: Spinnaker, Arial, sans-serif;\n color: black;\n background-color: #aed66c;\n border: 1px solid #4c5e2f;\n}\n",""]);const o=a},"AnswerRow.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".answer-row-grid {\n display: grid; \n grid-template-columns: 1fr 3fr 2fr 6fr 5fr;\n grid-gap: 1px; \n}\n\n.answer-title-element {\n background-color: rgba(235, 243, 250, 0.4);\n border: 1px solid grey;\n display: flex;\n align-items: center;\n justify-content: center;\n\n\ttext-shadow: -1px 1px 1px #ffffff,\n\t\t\t\t 1px 1px 1px #ffffff,\n\t\t\t\t 1px -1px 1px #ffffff,\n\t\t\t\t -1px -1px 1px #ffffff;\n}\n\n.answer-text-element {\n background-color: rgba(236, 244, 250, 0.4);\n border: 1px solid black;\n border-radius: 3px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n\ttext-shadow: -1px 1px 1px #ffffff,\n\t\t\t\t 1px 1px 1px #ffffff,\n\t\t\t\t 1px -1px 1px #ffffff,\n\t\t\t\t -1px -1px 1px #ffffff;\n}\n\n.answer-container-element {\n background-color: rgba(236, 244, 250, 0.4);\n border: 1px solid black;\n border-radius: 3px;\n padding: 2px;\n}\n\n.score_tile {\n font-size: 1em;\n border-radius: 4px;\n height: 20px;\n padding: 2px;\n margin: 2px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n}\n\n.note_span_tag {\n width: max-content;\n font-family: Spinnaker, Arial, sans-serif;\n color: black;\n background-color: #d6c66c;\n border: 1px solid #807642;\n}\n\n",""]);const o=a},"AnswerScores.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".not_a_word_tile {\n font-size: 1em;\n}\n.boggle_score_tile {\n width: 20px;\n font-family: Arial, Helvetica, sans-serif;\n color: rgb(21, 98, 241);\n background-color: rgb(231, 247, 248);\n border: 1px solid darkblue;\n}\n.scrabble_score_tile {\n width: 20px;\n font-family: Spinnaker, Arial, sans-serif;\n color: #2A1F1B;\n background-color: #ce9f73;\n border: 1px solid rgb(139, 107, 0);\n}\n",""]);const o=a},"AnswersPanel.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".answers-panel {\n height: 100%;\n width: 100%;\n}\n\n.answers-panel-answers {\n height: 100%;\n width: 100%;\n margin: 5px;\n padding: 5px;\n}\n\n\n\n.text-over-license-plate {\n background-color: rgba(236, 244, 250, 0.4);\n\ttext-shadow: -1px 1px 1px #ffffff,\n\t\t\t\t 1px 1px 1px #ffffff,\n\t\t\t\t 1px -1px 1px #ffffff,\n\t\t\t\t -1px -1px 1px #ffffff;\n}\n\n",""]);const o=a},"AnswersTable.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"/* .row {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n width: 100%;\n} */\n/* .column {\n display: flex;\n flex-direction: column;\n flex-basis: 100%;\n flex: 1;\n color: black;\n} */\n\n/* .selected-words-title {\n background-color: lightgrey;\n height: 1.5em;\n}\n\n.attempt-number-column {\n height: 2em;\n flex: 0 0 5%;\n}\n.attempt-number-column-color {\nbackground-color: whitesmoke;\n}\n.selected-word-column {\n height: 2em;\n flex: 0 0 15%;\n}\n.selected-word-column-color {\n background-color: rgb(253, 253, 161);\n}\n\n.scores-column {\n height: 2em;\n flex: 0 0 15%;\n}\n.scores-column-color {\n background-color: rgb(202, 231, 255);\n}\n\n.white-column {\n background-color: whitesmoke;\n height: 2em;\n}\n\n\n.difficulty-column {\n background-color: lightblue;\n height: 2em;\n flex: 0 0 30%;\n}\n\n.notes-column {\n background-color: lightgreen;\n height: 2em;\n} */\n\n.scroll-vertically {\n overflow-y: scroll;\n}",""]);const o=a},"AnswersTitleRow.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"",""]);const o=a},"Banner.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"/* top level container is grid: 10% : 80% : 10% */\n.page-header-container {\n display: grid; \n grid-template-columns: 10fr 80fr 10fr;\n grid-gap: 0px; \n}\n.hamburger-menu-container {\n flex: 0 0 10%;\n position: relative;\n display: inline-block; \n}\n.banner-container {\n flex: 0 0 60%;\n margin: auto;\n text-align: center;\n}\n/* empty-right-header-container requires no CSS */\n\n\n\n/* hamburger menu */\n.hamburger-menu {\n margin: 5px;\n width: 20px;\n height: 20px;\n}\n.dropdown-content {\n display: none;\n position: absolute;\n /* background-color: #f1f1f1; */\n min-width: 160px;\n /* box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); */\n z-index: 1;\n}\n.dropdown-content button {\n color: black;\n padding: 6px 6px;\n text-decoration: none;\n display: block;\n}\n.dropdown-content a:hover {\n background-color: #ddd;\n}\n.hamburger-menu-container:hover .dropdown-content {\n display: block;\n}\n\n\n/* page title */\n.banner-header {\n font-size: 2em;\n}\n\n/* See SystemMessagesSignboard.css */\n",""]);const o=a},"CurrentGameControls.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".current-game-controls-button {\n border-radius: 4px;\n font-size: 1.0em;\n}\n.current-game-controls {\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 95%;\n height: 15%;\n margin: 0 auto;\n justify-content: center;\n flex-flow: row nowrap;\n padding: 10px;\n column-gap: 10px;\n font-size: 1.5em;\n /* border: 1px solid grey; */\n}\n.current-game-controls-time {\n flex: 0 0 25%;\n padding: 5px;\n /* border: 1px solid grey; */\n}\n.current-game-controls-buttons {\n flex: 0 0 34%;\n padding: 5px;\n}\n.current-game-controls-hint {\n flex: 0 0 41%;\n padding: 5px;\n}\n\n.reset-icon-color {\n color: red;\n}\n",""]);const o=a},"FeedbackPanel.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".feedback-panel{\n background-color: rgb(248, 248, 93);\n margin: 15px;\n color: black;\n}\n.feedback-button {\n font-size: 1em;\n border-radius: 8px;\n width: 140px;\n height: 30px;\n padding: 2px;\n margin: 2px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n font-family: sans-serif;\n /* color: rgb(21, 98, 241); */\n /* background-color: rgb(231, 247, 248); */\n border: 1px solid black;\n}\n\n",""]);const o=a},"GameStatusMessagesSignboard.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"\n.hint-message {\n padding: 5px;\n font-family: 'Trebuchet MS';\n font-style: italic;\n background-color: #ECF4FA;\n white-space: pre;\n opacity: 1;\n}\n\n.checked-answer-message {\n padding: 5px;\n font-weight: bold;\n background-color: #ECF4FA;\n font-family: 'Trebuchet MS';\n}\n\n\n/* */\n\n.fade-out-in {\n animation-duration: 1s;\n animation-name: fade_in_out_keyframes;\n}\n\n\n@keyframes fade_in_out_keyframes {\n from {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n",""]);const o=a},"LicensePlateSolutionEditorFreeEntry.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>m});var i=n(81),r=n.n(i),s=n(645),a=n.n(s),o=n(667),l=n.n(o),c=new URL(n(304),n.b),g=new URL(n(804),n.b),d=a()(r()),u=l()(c),p=l()(g);d.push([e.id,".license-plate-frame {\n background-image: url("+u+");\n background-size: cover;\n border-radius: 10px;\n width: 1000px;\n height: 600px;\n margin: 5px;\n border: 2px solid black;\n\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n.license-plate-frame-interior {\n /* background-color: silver; */\n background-image: url("+p+");\n background-size: cover;\n border-radius: 8px;\n width: 90%;\n height: 70%;\n border: 2px solid darkblue;\n padding: 20px;\n margin: 0 auto;\n}\n.license-plate-flex-container {\n height: 100%;\n width: 100%;\n align-items: center;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.answers-container {\n height: 100%;\n width: 100%;\n}\n.top-of-license-frame-size {\n width: 95%;\n height: 15%;\n margin: 0 auto;\n}\n.license-plate-top {\n width: 95%;\n height: 20%;\n /* border: 1px dashed red; */\n}\n.license-plate-text {\n width: 95%;\n height: 60%;\n /* border: 1px dashed white; */\n margin: auto;\n display: flex;\n flex-flow: row nowrap;\n justify-content: center;\n align-items: center;\n}\n.license-plate-char {\n font-family: sans-serif;\n color: black;\n font-size: 10em;\n transition: all 1s ease;\n}\n.input-no-border {\n border: none;\n background: none;\n text-align: center;\n}\n.input-invalid {\n color: red;\n transition: all 0.2s ease;\n}\n.license-plate-bottom {\n width: 95%;\n height: 20%;\n /* border: 1px dashed red; */\n}\n\n",""]);const m=d},"PuzzleSummary.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".puzzle-description {\n font-size: 1.5em;\n margin: 5px;\n}\n.mini-license-plate {\n font-size: 1.5em;\n border-radius: 4px;\n width: 150px;\n height: 40px;\n padding: 2px;\n margin: 2px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n font-family: sans-serif;\n color: rgb(21, 98, 241);\n background-color: rgb(231, 247, 248);\n border: 1px solid darkblue;\n}\n\n",""]);const o=a},"StartNewGameControls.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".start-new-game-control {\n font-size: 1.2em;\n}\n\n.user-specified-text-input {\n width: 3em;\n}\n\n.start-user-specified-game-button {\n width: 11em;\n}",""]);const o=a},"TopOfLicensePlateFrame.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".top-of-license-frame {\n display: grid; \n grid-template-columns: 50fr 3fr 47fr;\n grid-gap: 0px; \n padding: 5px;\n /* margin: 0 auto; */\n /* border: 1px solid grey; */\n}\n.top-of-license-frame-child {\n margin: 5px; \n padding: 5px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n/* .top-of-license-frame-gap {\n border: 1px solid green;\n} */\n",""]);const o=a},"app.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"body {\n margin: 0px;\n}\n.app {\n /* Debbie's choice */\n /* background-color: rgb(134, 140, 160); */\n\n background-image: linear-gradient(rgb(183, 224, 240), rgb(85, 145, 168));\n padding: 10px;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n}\n.main-container-width {\n width: 1000px;\n margin: 5px;\n}\n",""]);const o=a},"css/general.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,"\n.flexbox-centering {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.flexbox-centering-text {\n display: inline-block; \n}\n\n",""]);const o=a},"css/loading.io.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>o});var i=n(81),r=n.n(i),s=n(645),a=n.n(s)()(r());a.push([e.id,".lds-ellipsis {\n display: inline-block;\n position: relative;\n width: 80px;\n height: 20px;\n}\n.lds-ellipsis div {\n position: absolute;\n top: 7px;\n width: 13px;\n height: 13px;\n border-radius: 50%;\n background: rgb(95, 185, 50);\n animation-timing-function: cubic-bezier(0, 1, 1, 0);\n}\n.lds-ellipsis div:nth-child(1) {\n left: 8px;\n animation: lds-ellipsis1 0.6s infinite;\n}\n.lds-ellipsis div:nth-child(2) {\n left: 8px;\n animation: lds-ellipsis2 0.6s infinite;\n}\n.lds-ellipsis div:nth-child(3) {\n left: 32px;\n animation: lds-ellipsis2 0.6s infinite;\n}\n.lds-ellipsis div:nth-child(4) {\n left: 56px;\n animation: lds-ellipsis3 0.6s infinite;\n}\n@keyframes lds-ellipsis1 {\n 0% {\n transform: scale(0);\n }\n 100% {\n transform: scale(1);\n }\n}\n@keyframes lds-ellipsis3 {\n 0% {\n transform: scale(1);\n }\n 100% {\n transform: scale(0);\n }\n}\n@keyframes lds-ellipsis2 {\n 0% {\n transform: translate(0, 0);\n }\n 100% {\n transform: translate(24px, 0);\n }\n}\n",""]);const o=a},"css/toggle-radios.css":(e,t,n)=>{n.r(t),n.d(t,{default:()=>f});var i=n(81),r=n.n(i),s=n(645),a=n.n(s),o=n(667),l=n.n(o),c=new URL(n(68),n.b),g=new URL(n(578),n.b),d=new URL(n(192),n.b),u=new URL(n(806),n.b),p=a()(r()),m=l()(c),b=l()(g),A=l()(d),I=l()(u);p.push([e.id,"/*\nToggle Radios v1.4\nby Adam Culpepper | @adamculpepper\nhttps://github.com/adamculpepper/toggle-radios\n*/\n\n/* Customizable styles */\n\n/* Colors: Default (blue) */\n.toggle-radio > input + label {background:#f5f5f5; border:1px solid rgba(0, 0, 0, 0.2); border-width:1px 1px 0 1px;}\n.toggle-radio > input:last-of-type + label {border-bottom-width:1px;}\n.toggle-radio > input:checked + label {background:lightblue;}\n\n/* Rounded corners */\n.toggle-radio input:first-of-type + label {border-radius:4px 4px 0 0;}\n.toggle-radio input:last-of-type + label {border-radius:0 0 4px 4px;}\n\n/* Indicators for smaller devices (stacked) */\n.toggle-radio > input + label:before {content:''; display:inline-block; width:16px; height:16px; margin-right:0.50rem; background-image:url("+m+"); background-repeat:no-repeat; background-position:center center; background-size:16px 16px;}\n.toggle-radio > input:checked + label:before {background-image:url("+b+");}\n\n/* //////////////////////////\nCORE STYLES BELOW - NO TOUCHY\n////////////////////////// */\n.toggle-radio {display:inline-block; vertical-align:middle;}\n.toggle-radio > input[type='radio'] {display:none;}\n.toggle-radio > input[disabled] + label {opacity:0.50;}\n.toggle-radio > input[disabled] + label:hover {cursor:not-allowed;}\n.toggle-radio > input + label {display:flex; margin-bottom:0; padding:5px 10px; cursor:pointer; align-items:center;}\n\n/* Transitions */\n.toggle-radio > input:checked + label {transition:background 300ms linear;}\n\n/* //////////////////////////\nCORE STYLES ABOVE - NO TOUCHY\n////////////////////////// */\n\n/* Style: Rounded */\n.toggle-radio[data-style='rounded'] > input:first-of-type + label\t\t{border-radius:20px 20px 0 0;}\n.toggle-radio[data-style='rounded'] > input:last-of-type + label\t\t{border-radius:0 0 20px 20px;}\n\n/* Style: Square */\n.toggle-radio[data-style='square'] > input + label\t\t\t{border-radius:0;}\n\n/* Color */\n.toggle-radio[data-color] > input + label\t\t\t\t\t{color:#fff;}\n.toggle-radio[data-color] > input + label:before \t\t\t{background-image:url("+A+");}\n.toggle-radio[data-color] > input:checked + label:before\t{background-image:url("+I+");}\n\n/* Color: Red */\n.toggle-radio[data-color='red'] > input + label\t\t\t\t{background:#e74c3c;}\n.toggle-radio[data-color='red'] > input:checked + label\t\t{background:#9a0000;}\n\n/* Color: Orange */\n.toggle-radio[data-color='orange'] > input + label\t\t\t{background:#e67e22;}\n.toggle-radio[data-color='orange'] > input:checked + label\t{background:#993100;}\n \n/* Color: Yellow */\n.toggle-radio[data-color='yellow'] > input + label\t\t\t{background:#f1c30f;}\n.toggle-radio[data-color='yellow'] > input:checked + label\t{background:#a47600;}\n\n/* Color: Green */\n.toggle-radio[data-color='green'] > input + label\t\t\t{background:#2ecc71;}\n.toggle-radio[data-color='green'] > input:checked + label\t{background:#007f24;}\n\n/* Color: Blue */\n.toggle-radio[data-color='blue'] > input + label\t\t\t{background:#3498db;}\n.toggle-radio[data-color='blue'] > input:checked + label\t{background:#004b8e;}\n\n/* Color: Purple */\n.toggle-radio[data-color='purple'] > input + label\t\t\t{background:#aa66cc;}\n.toggle-radio[data-color='purple'] > input:checked + label\t{background:#5d197f;}\n\n/* Color: Gray */\n.toggle-radio[data-color='gray'] > input + label\t\t\t{background:#555555;}\n.toggle-radio[data-color='gray'] > input:checked + label\t{background:#080808;}\n\n\n/* ------------------------------ */\n\n/* Bootstrap Breakpoints */\n\n/* Small (sm) and up */\n@media (min-width:576px) {\n\n}\n\n\n/* Medium (md) and up */\n@media (min-width:768px) {\n\n}\n\n\n/* Large (lg) and up */\n@media (min-width:992px) {\n\t.toggle-radio > input + label\t\t\t\t{display:inline-block; float:left; border-width:1px 0 1px 1px;}\n\t.toggle-radio > input:last-of-type + label \t{border-right-width:1px;}\n\t.toggle-radio > input + label:before\t\t{display:none;}\n\n\t/* Border Radius */\n\t.toggle-radio input:first-of-type + label\t{border-radius:4px 0 0 4px;}\n\t.toggle-radio input:last-of-type + label \t{border-radius:0 4px 4px 0;}\n\n\t/* Rounded */\n\t.toggle-radio[data-style='rounded'] > input:first-of-type + label {border-radius:500px 0 0 500px;}\n\t.toggle-radio[data-style='rounded'] > input:last-of-type + label {border-radius:0 500px 500px 0;}\n}\n\n/* Extra Large (xl) and up */\n@media (min-width:1200px) {\n\n}\n",""]);const f=p},"AboutPanel.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>m});var i=n(91),r=n.n(i),s=new URL(n(746),n.b),a=new URL(n(481),n.b),o=new URL(n(611),n.b),l=new URL(n(19),n.b),c=new URL(n(647),n.b),g=new URL(n(930),n.b),d=new URL(n(321),n.b),u=r()(s),p=r()(a);const m='\n\n'},"AnswerDifficulty.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"AnswerRow.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"AnswerScores.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n\n'},"AnswersPanel.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n\n'},"AnswersTable.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"AnswersTitleRow.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i="\n"},"Banner.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>l});var i=n(91),r=n.n(i),s=new URL(n(286),n.b),a=new URL(n(746),n.b),o=new URL(n(481),n.b);const l='\n '},"CurrentGameControls.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n\n'},"FeedbackPanel.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n\n'},"GameStatusMessagesSignboard.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"InProcessIndicator.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"LicensePlateSolutionEditorFreeEntry.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"PuzzleSummary.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"StartNewGameControls.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"SystemMessagesSignboard.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='\n'},"TopOfLicensePlateFrame.html":(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});const i='