@nebularstreams/overlay-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +44 -0
- package/preview/assets/images/favicon.ico +0 -0
- package/preview/assets/images/favicon.png +0 -0
- package/preview/assets/images/login-right.webp +0 -0
- package/preview/assets/images/nebular.color.100h.png +0 -0
- package/preview/assets/images/nebular.color.white.100h.png +0 -0
- package/preview/assets/images/nebular.medallion.transparent..png +0 -0
- package/preview/assets/images/testcard.png +0 -0
- package/preview/assets/webfonts/fa-brands-400.woff2 +0 -0
- package/preview/assets/webfonts/fa-solid-900.woff2 +0 -0
- package/preview/bundle.min.js +6 -0
- package/preview/index.css +28 -0
- package/preview/index.html +23 -0
- package/readme.md +132 -0
- package/skill/nebular-overlay/SKILL.md +56 -0
- package/skill/nebular-overlay/agents/openai.yaml +4 -0
- package/skill/nebular-overlay/references/examples.md +327 -0
- package/skill/nebular-overlay/references/manifest.md +153 -0
- package/skill/nebular-overlay/references/runtime-and-design.md +88 -0
- package/skill/nebular-overlay/scripts/validate-templates.mjs +244 -0
- package/templates/all/broadcast/breaking-news/index.html +100 -0
- package/templates/all/broadcast/breaking-news/manifest.json +9 -0
- package/templates/all/broadcast/empty/index.html +46 -0
- package/templates/all/broadcast/empty/manifest.json +7 -0
- package/templates/all/broadcast/empty/nebular.medallion.transparent.png +0 -0
- package/templates/all/broadcast/event-countdown/index.html +160 -0
- package/templates/all/broadcast/event-countdown/logo.png +0 -0
- package/templates/all/broadcast/event-countdown/manifest.json +33 -0
- package/templates/all/broadcast/lower-third/index.html +77 -0
- package/templates/all/broadcast/lower-third/manifest.json +8 -0
- package/templates/all/broadcast/newsticker/index.html +153 -0
- package/templates/all/broadcast/newsticker/manifest.json +21 -0
- package/templates/all/broadcast/newsticker-frames/background-label-green.png +0 -0
- package/templates/all/broadcast/newsticker-frames/background-label-orange.png +0 -0
- package/templates/all/broadcast/newsticker-frames/banner.png +0 -0
- package/templates/all/broadcast/newsticker-frames/index.html +229 -0
- package/templates/all/broadcast/newsticker-frames/manifest.json +20 -0
- package/templates/all/broadcast/weather/index.html +382 -0
- package/templates/all/broadcast/weather/manifest.json +104 -0
- package/templates/all/engagement/call-to-action/index.html +116 -0
- package/templates/all/engagement/call-to-action/manifest.json +12 -0
- package/templates/all/engagement/chat/index.html +121 -0
- package/templates/all/engagement/chat/manifest.json +32 -0
- package/templates/all/engagement/post/index.html +132 -0
- package/templates/all/engagement/post/manifest.json +31 -0
- package/templates/all/gambling/bingo/index.html +227 -0
- package/templates/all/gambling/bingo/manifest.json +144 -0
- package/templates/all/gambling/keno/index.html +202 -0
- package/templates/all/gambling/keno/manifest.json +129 -0
- package/templates/all/gambling/lottery/index.html +159 -0
- package/templates/all/gambling/lottery/manifest.json +95 -0
- package/templates/all/gambling/prize-wall/index.html +256 -0
- package/templates/all/gambling/prize-wall/manifest.json +108 -0
- package/templates/all/gambling/roulette/index.html +200 -0
- package/templates/all/gambling/roulette/manifest.json +78 -0
- package/templates/all/gaming/battleship/index.html +578 -0
- package/templates/all/gaming/battleship/manifest.json +279 -0
- package/templates/all/gaming/gta/mission/index.html +121 -0
- package/templates/all/gaming/gta/mission/manifest.json +38 -0
- package/templates/all/sports/football/scoreboard/index.html +115 -0
- package/templates/all/sports/football/scoreboard/manifest.json +54 -0
- package/templates/all/sports/tennis/scoreboard/index.html +120 -0
- package/templates/all/sports/tennis/scoreboard/manifest.json +92 -0
- package/templates/all/trivia/audience-poll/index.html +60 -0
- package/templates/all/trivia/audience-poll/manifest.json +26 -0
- package/templates/all/trivia/classic-quiz/index.html +49 -0
- package/templates/all/trivia/classic-quiz/manifest.json +15 -0
- package/templates/all/trivia/lightning-round/index.html +126 -0
- package/templates/all/trivia/lightning-round/manifest.json +27 -0
- package/templates/all/trivia/pasapalabra/index.html +249 -0
- package/templates/all/trivia/pasapalabra/manifest.json +68 -0
- package/templates/all/trivia/quiz-deck/index.html +58 -0
- package/templates/all/trivia/quiz-deck/manifest.json +25 -0
- package/templates/all/trivia/true-or-false/index.html +81 -0
- package/templates/all/trivia/true-or-false/manifest.json +27 -0
- package/templates/basic/broadcast/empty/index.html +46 -0
- package/templates/basic/broadcast/empty/manifest.json +7 -0
- package/templates/basic/broadcast/empty/nebular.medallion.transparent.png +0 -0
- package/templates/basic/broadcast/event-countdown/index.html +160 -0
- package/templates/basic/broadcast/event-countdown/logo.png +0 -0
- package/templates/basic/broadcast/event-countdown/manifest.json +33 -0
- package/templates/basic/broadcast/lower-third/index.html +77 -0
- package/templates/basic/broadcast/lower-third/manifest.json +8 -0
- package/templates/basic/broadcast/newsticker/index.html +153 -0
- package/templates/basic/broadcast/newsticker/manifest.json +21 -0
- package/templates/basic/broadcast/weather/index.html +382 -0
- package/templates/basic/broadcast/weather/manifest.json +104 -0
- package/templates/basic/engagement/call-to-action/index.html +116 -0
- package/templates/basic/engagement/call-to-action/manifest.json +12 -0
- package/templates/basic/engagement/chat/index.html +121 -0
- package/templates/basic/engagement/chat/manifest.json +32 -0
- package/templates/basic/engagement/post/index.html +132 -0
- package/templates/basic/engagement/post/manifest.json +31 -0
- package/templates/basic/sports/football/scoreboard/index.html +115 -0
- package/templates/basic/sports/football/scoreboard/manifest.json +54 -0
- package/templates/basic/sports/tennis/scoreboard/index.html +120 -0
- package/templates/basic/sports/tennis/scoreboard/manifest.json +92 -0
- package/templates/debug/testing/security-probe/forbidden.js +1 -0
- package/templates/debug/testing/security-probe/forbidden.json +1 -0
- package/templates/debug/testing/security-probe/forbidden.mp4 +1 -0
- package/templates/debug/testing/security-probe/forbidden.svg +1 -0
- package/templates/debug/testing/security-probe/index.html +367 -0
- package/templates/debug/testing/security-probe/manifest.json +13 -0
- package/templates/empty/broadcast/empty/index.html +46 -0
- package/templates/empty/broadcast/empty/manifest.json +7 -0
- package/templates/empty/broadcast/empty/nebular.medallion.transparent.png +0 -0
- package/templates/games/gambling/bingo/index.html +227 -0
- package/templates/games/gambling/bingo/manifest.json +56 -0
- package/templates/games/gambling/keno/index.html +202 -0
- package/templates/games/gambling/keno/manifest.json +129 -0
- package/templates/games/gambling/lottery/index.html +159 -0
- package/templates/games/gambling/lottery/manifest.json +95 -0
- package/templates/games/gambling/prize-wall/index.html +256 -0
- package/templates/games/gambling/prize-wall/manifest.json +108 -0
- package/templates/games/gambling/roulette/index.html +200 -0
- package/templates/games/gambling/roulette/manifest.json +78 -0
- package/templates/games/gaming/battleship/index.html +578 -0
- package/templates/games/gaming/battleship/manifest.json +279 -0
- package/templates/games/gaming/gta/mission/index.html +121 -0
- package/templates/games/gaming/gta/mission/manifest.json +38 -0
- package/templates/games/trivia/audience-poll/index.html +60 -0
- package/templates/games/trivia/audience-poll/manifest.json +26 -0
- package/templates/games/trivia/classic-quiz/index.html +49 -0
- package/templates/games/trivia/classic-quiz/manifest.json +15 -0
- package/templates/games/trivia/lightning-round/index.html +126 -0
- package/templates/games/trivia/lightning-round/manifest.json +27 -0
- package/templates/games/trivia/pasapalabra/index.html +249 -0
- package/templates/games/trivia/pasapalabra/manifest.json +68 -0
- package/templates/games/trivia/quiz-deck/index.html +58 -0
- package/templates/games/trivia/quiz-deck/manifest.json +25 -0
- package/templates/games/trivia/true-or-false/index.html +81 -0
- package/templates/games/trivia/true-or-false/manifest.json +27 -0
- package/tool/cli.cjs +7 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
{
|
|
2
|
+
"instructions": "Place the fleet by selecting every coordinate occupied by a ship; adjoining cells form one vessel, so leave water between separate boats. Keep Fleet display hidden during play, then add every coordinate fired upon by the player. The overlay determines hits, misses and sunk vessels automatically. Reveal the fleet when the round ends. Use Reset round to clear all shots and hide the fleet again, then press Update.",
|
|
3
|
+
"meta": {
|
|
4
|
+
"content/title": {
|
|
5
|
+
"type": "string",
|
|
6
|
+
"phase": "edit",
|
|
7
|
+
"label": "Title", "hint": "Enter title",
|
|
8
|
+
"default": "Fleet Command"
|
|
9
|
+
},
|
|
10
|
+
"content/player": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"phase": "edit",
|
|
13
|
+
"label": "Player", "hint": "Enter player name",
|
|
14
|
+
"default": "John Carter"
|
|
15
|
+
},
|
|
16
|
+
"content/location": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"phase": "edit",
|
|
19
|
+
"label": "Player location", "hint": "Enter player location",
|
|
20
|
+
"default": "New York · NY"
|
|
21
|
+
},
|
|
22
|
+
"board/fleet": {
|
|
23
|
+
"type": "multi",
|
|
24
|
+
"phase": "edit",
|
|
25
|
+
"container": "big",
|
|
26
|
+
"label": "Fleet positions", "hint": "Every coordinate occupied by the player's ships",
|
|
27
|
+
"choose": [
|
|
28
|
+
"A1",
|
|
29
|
+
"A2",
|
|
30
|
+
"A3",
|
|
31
|
+
"A4",
|
|
32
|
+
"A5",
|
|
33
|
+
"A6",
|
|
34
|
+
"A7",
|
|
35
|
+
"A8",
|
|
36
|
+
"A9",
|
|
37
|
+
"A10",
|
|
38
|
+
"B1",
|
|
39
|
+
"B2",
|
|
40
|
+
"B3",
|
|
41
|
+
"B4",
|
|
42
|
+
"B5",
|
|
43
|
+
"B6",
|
|
44
|
+
"B7",
|
|
45
|
+
"B8",
|
|
46
|
+
"B9",
|
|
47
|
+
"B10",
|
|
48
|
+
"C1",
|
|
49
|
+
"C2",
|
|
50
|
+
"C3",
|
|
51
|
+
"C4",
|
|
52
|
+
"C5",
|
|
53
|
+
"C6",
|
|
54
|
+
"C7",
|
|
55
|
+
"C8",
|
|
56
|
+
"C9",
|
|
57
|
+
"C10",
|
|
58
|
+
"D1",
|
|
59
|
+
"D2",
|
|
60
|
+
"D3",
|
|
61
|
+
"D4",
|
|
62
|
+
"D5",
|
|
63
|
+
"D6",
|
|
64
|
+
"D7",
|
|
65
|
+
"D8",
|
|
66
|
+
"D9",
|
|
67
|
+
"D10",
|
|
68
|
+
"E1",
|
|
69
|
+
"E2",
|
|
70
|
+
"E3",
|
|
71
|
+
"E4",
|
|
72
|
+
"E5",
|
|
73
|
+
"E6",
|
|
74
|
+
"E7",
|
|
75
|
+
"E8",
|
|
76
|
+
"E9",
|
|
77
|
+
"E10",
|
|
78
|
+
"F1",
|
|
79
|
+
"F2",
|
|
80
|
+
"F3",
|
|
81
|
+
"F4",
|
|
82
|
+
"F5",
|
|
83
|
+
"F6",
|
|
84
|
+
"F7",
|
|
85
|
+
"F8",
|
|
86
|
+
"F9",
|
|
87
|
+
"F10",
|
|
88
|
+
"G1",
|
|
89
|
+
"G2",
|
|
90
|
+
"G3",
|
|
91
|
+
"G4",
|
|
92
|
+
"G5",
|
|
93
|
+
"G6",
|
|
94
|
+
"G7",
|
|
95
|
+
"G8",
|
|
96
|
+
"G9",
|
|
97
|
+
"G10",
|
|
98
|
+
"H1",
|
|
99
|
+
"H2",
|
|
100
|
+
"H3",
|
|
101
|
+
"H4",
|
|
102
|
+
"H5",
|
|
103
|
+
"H6",
|
|
104
|
+
"H7",
|
|
105
|
+
"H8",
|
|
106
|
+
"H9",
|
|
107
|
+
"H10",
|
|
108
|
+
"I1",
|
|
109
|
+
"I2",
|
|
110
|
+
"I3",
|
|
111
|
+
"I4",
|
|
112
|
+
"I5",
|
|
113
|
+
"I6",
|
|
114
|
+
"I7",
|
|
115
|
+
"I8",
|
|
116
|
+
"I9",
|
|
117
|
+
"I10",
|
|
118
|
+
"J1",
|
|
119
|
+
"J2",
|
|
120
|
+
"J3",
|
|
121
|
+
"J4",
|
|
122
|
+
"J5",
|
|
123
|
+
"J6",
|
|
124
|
+
"J7",
|
|
125
|
+
"J8",
|
|
126
|
+
"J9",
|
|
127
|
+
"J10"
|
|
128
|
+
],
|
|
129
|
+
"cols": 10,
|
|
130
|
+
"rows": 10,
|
|
131
|
+
"responsive": true,
|
|
132
|
+
"minCellWidth": "2.54rem",
|
|
133
|
+
"default": [
|
|
134
|
+
"A2", "A3", "A4", "A5",
|
|
135
|
+
"C3", "C4", "C5",
|
|
136
|
+
"F7", "F8", "F9",
|
|
137
|
+
"H2", "H3",
|
|
138
|
+
"J8", "J9"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"content/playPlayer": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"phase": "play",
|
|
144
|
+
"label": "Player", "hint": "Player name displayed during the round",
|
|
145
|
+
"source": "content/player",
|
|
146
|
+
"readonly": true
|
|
147
|
+
},
|
|
148
|
+
"board/fleetVisibility": {
|
|
149
|
+
"type": "choose",
|
|
150
|
+
"phase": "play",
|
|
151
|
+
"label": "Fleet display", "hint": "Hide the fleet during play or reveal it after the round",
|
|
152
|
+
"choose": ["hidden", "revealed"],
|
|
153
|
+
"default": "hidden"
|
|
154
|
+
},
|
|
155
|
+
"board/shots": {
|
|
156
|
+
"type": "multi",
|
|
157
|
+
"phase": "play",
|
|
158
|
+
"container": "big",
|
|
159
|
+
"label": "Player shots", "hint": "Coordinates fired upon by the player",
|
|
160
|
+
"choose": [
|
|
161
|
+
"A1",
|
|
162
|
+
"A2",
|
|
163
|
+
"A3",
|
|
164
|
+
"A4",
|
|
165
|
+
"A5",
|
|
166
|
+
"A6",
|
|
167
|
+
"A7",
|
|
168
|
+
"A8",
|
|
169
|
+
"A9",
|
|
170
|
+
"A10",
|
|
171
|
+
"B1",
|
|
172
|
+
"B2",
|
|
173
|
+
"B3",
|
|
174
|
+
"B4",
|
|
175
|
+
"B5",
|
|
176
|
+
"B6",
|
|
177
|
+
"B7",
|
|
178
|
+
"B8",
|
|
179
|
+
"B9",
|
|
180
|
+
"B10",
|
|
181
|
+
"C1",
|
|
182
|
+
"C2",
|
|
183
|
+
"C3",
|
|
184
|
+
"C4",
|
|
185
|
+
"C5",
|
|
186
|
+
"C6",
|
|
187
|
+
"C7",
|
|
188
|
+
"C8",
|
|
189
|
+
"C9",
|
|
190
|
+
"C10",
|
|
191
|
+
"D1",
|
|
192
|
+
"D2",
|
|
193
|
+
"D3",
|
|
194
|
+
"D4",
|
|
195
|
+
"D5",
|
|
196
|
+
"D6",
|
|
197
|
+
"D7",
|
|
198
|
+
"D8",
|
|
199
|
+
"D9",
|
|
200
|
+
"D10",
|
|
201
|
+
"E1",
|
|
202
|
+
"E2",
|
|
203
|
+
"E3",
|
|
204
|
+
"E4",
|
|
205
|
+
"E5",
|
|
206
|
+
"E6",
|
|
207
|
+
"E7",
|
|
208
|
+
"E8",
|
|
209
|
+
"E9",
|
|
210
|
+
"E10",
|
|
211
|
+
"F1",
|
|
212
|
+
"F2",
|
|
213
|
+
"F3",
|
|
214
|
+
"F4",
|
|
215
|
+
"F5",
|
|
216
|
+
"F6",
|
|
217
|
+
"F7",
|
|
218
|
+
"F8",
|
|
219
|
+
"F9",
|
|
220
|
+
"F10",
|
|
221
|
+
"G1",
|
|
222
|
+
"G2",
|
|
223
|
+
"G3",
|
|
224
|
+
"G4",
|
|
225
|
+
"G5",
|
|
226
|
+
"G6",
|
|
227
|
+
"G7",
|
|
228
|
+
"G8",
|
|
229
|
+
"G9",
|
|
230
|
+
"G10",
|
|
231
|
+
"H1",
|
|
232
|
+
"H2",
|
|
233
|
+
"H3",
|
|
234
|
+
"H4",
|
|
235
|
+
"H5",
|
|
236
|
+
"H6",
|
|
237
|
+
"H7",
|
|
238
|
+
"H8",
|
|
239
|
+
"H9",
|
|
240
|
+
"H10",
|
|
241
|
+
"I1",
|
|
242
|
+
"I2",
|
|
243
|
+
"I3",
|
|
244
|
+
"I4",
|
|
245
|
+
"I5",
|
|
246
|
+
"I6",
|
|
247
|
+
"I7",
|
|
248
|
+
"I8",
|
|
249
|
+
"I9",
|
|
250
|
+
"I10",
|
|
251
|
+
"J1",
|
|
252
|
+
"J2",
|
|
253
|
+
"J3",
|
|
254
|
+
"J4",
|
|
255
|
+
"J5",
|
|
256
|
+
"J6",
|
|
257
|
+
"J7",
|
|
258
|
+
"J8",
|
|
259
|
+
"J9",
|
|
260
|
+
"J10"
|
|
261
|
+
],
|
|
262
|
+
"cols": 10,
|
|
263
|
+
"rows": 10,
|
|
264
|
+
"responsive": true,
|
|
265
|
+
"minCellWidth": "2.54rem",
|
|
266
|
+
"default": ["A3", "B8", "D4", "F8", "H9", "J8"]
|
|
267
|
+
},
|
|
268
|
+
"board/reset": {
|
|
269
|
+
"type": "reset",
|
|
270
|
+
"phase": "play",
|
|
271
|
+
"icon": "undo",
|
|
272
|
+
"text": "Reset round", "hint": "Clear all shots and hide the fleet for a new round",
|
|
273
|
+
"values": {
|
|
274
|
+
"board/fleetVisibility": "hidden",
|
|
275
|
+
"board/shots": []
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>GTA Mission Panel</title>
|
|
6
|
+
<style>
|
|
7
|
+
* {
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
html, body {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
margin: 0;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
background: transparent;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
body {
|
|
20
|
+
color: #fff;
|
|
21
|
+
font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif;
|
|
22
|
+
letter-spacing: .035em;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.mission {
|
|
26
|
+
position: absolute;
|
|
27
|
+
right: 5%;
|
|
28
|
+
top: 9%;
|
|
29
|
+
width: 34rem;
|
|
30
|
+
padding: 1.6rem 1.8rem;
|
|
31
|
+
background: rgba(8, 8, 8, .88);
|
|
32
|
+
border-left: .55rem solid #78d84b;
|
|
33
|
+
box-shadow: 0 1rem 3rem #0008;
|
|
34
|
+
transform: skewX(-2deg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.eyebrow {
|
|
38
|
+
color: #78d84b;
|
|
39
|
+
font: 700 .8rem system-ui, sans-serif;
|
|
40
|
+
letter-spacing: .22em;
|
|
41
|
+
text-transform: uppercase;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
h1 {
|
|
45
|
+
margin: .25rem 0 .5rem;
|
|
46
|
+
font-size: 2.6rem;
|
|
47
|
+
text-transform: uppercase;
|
|
48
|
+
text-shadow: .16rem .16rem 0 #000;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.objective {
|
|
52
|
+
margin: 0 0 1.2rem;
|
|
53
|
+
color: #ddd;
|
|
54
|
+
font: 600 1rem system-ui, sans-serif;
|
|
55
|
+
letter-spacing: normal;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.footer {
|
|
59
|
+
display: flex;
|
|
60
|
+
justify-content: space-between;
|
|
61
|
+
align-items: center;
|
|
62
|
+
gap: 1rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.progress {
|
|
66
|
+
flex: 1;
|
|
67
|
+
height: .7rem;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
background: #333;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.progress span {
|
|
73
|
+
display: block;
|
|
74
|
+
width: 65%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
background: #78d84b;
|
|
77
|
+
transition: width .35s ease;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.reward {
|
|
81
|
+
color: #8fea62;
|
|
82
|
+
font-size: 1.45rem;
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
}
|
|
85
|
+
</style>
|
|
86
|
+
</head>
|
|
87
|
+
<body>
|
|
88
|
+
<section class="mission">
|
|
89
|
+
<div class="eyebrow">Current objective</div>
|
|
90
|
+
<h1 id="mission">THE GETAWAY</h1>
|
|
91
|
+
<p class="objective" id="objective">Reach the safehouse</p>
|
|
92
|
+
<div class="footer">
|
|
93
|
+
<div class="progress"><span id="progress"></span></div>
|
|
94
|
+
<div class="reward" id="reward">$5,000</div>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
<script>
|
|
98
|
+
|
|
99
|
+
// convenience to assign values
|
|
100
|
+
const $ = (name, value) => {
|
|
101
|
+
const element = document.getElementById(name);
|
|
102
|
+
if (element) {
|
|
103
|
+
if (value !== undefined) element.textContent = String(value);
|
|
104
|
+
else return element;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function setProgress(value) {
|
|
109
|
+
const percentage = Math.max(0, Math.min(100, Number(value)));
|
|
110
|
+
$("progress").style.width = `${percentage}%`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
window.addEventListener("nebular-overlay:update", ({detail}) => {
|
|
114
|
+
if (detail.mission?.title != null) $("mission", detail.mission.title);
|
|
115
|
+
if (detail.mission?.objective != null) $("objective", detail.mission.objective);
|
|
116
|
+
if (detail.mission?.reward != null) $("reward", detail.mission.reward);
|
|
117
|
+
if (detail.mission?.progress != null) setProgress(detail.mission.progress);
|
|
118
|
+
});
|
|
119
|
+
</script>
|
|
120
|
+
</body>
|
|
121
|
+
</html>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"instructions": "Enter the mission title, objective and reward, then adjust progress as the mission advances. Press Update to refresh the mission panel without changing unrelated fields.",
|
|
3
|
+
"meta": {
|
|
4
|
+
"mission/title": {
|
|
5
|
+
"type": "string",
|
|
6
|
+
"phase": "edit",
|
|
7
|
+
"label": "Mission title", "hint": "Enter mission title",
|
|
8
|
+
"default": "THE GETAWAY"
|
|
9
|
+
},
|
|
10
|
+
"mission/objective": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"phase": "edit",
|
|
13
|
+
"label": "Objective", "hint": "Enter objective",
|
|
14
|
+
"default": "Reach the safehouse"
|
|
15
|
+
},
|
|
16
|
+
"mission/reward": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"phase": "edit",
|
|
19
|
+
"label": "Reward", "hint": "Enter reward",
|
|
20
|
+
"default": "$5,000"
|
|
21
|
+
},
|
|
22
|
+
"mission/playObjective": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"phase": "play",
|
|
25
|
+
"label": "Objective", "hint": "Mission objective displayed during play",
|
|
26
|
+
"source": "mission/objective",
|
|
27
|
+
"readonly": true
|
|
28
|
+
},
|
|
29
|
+
"mission/progress": {
|
|
30
|
+
"type": "range",
|
|
31
|
+
"phase": "play",
|
|
32
|
+
"label": "Progress", "hint": "Current completion percentage for the mission",
|
|
33
|
+
"min": 0,
|
|
34
|
+
"max": 100,
|
|
35
|
+
"default": 65
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Audience Poll</title>
|
|
6
|
+
<style>
|
|
7
|
+
* { box-sizing: border-box; }
|
|
8
|
+
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: transparent; }
|
|
9
|
+
body { --accent: #36d1ff; color: white; font-family: Inter, Arial, sans-serif; }
|
|
10
|
+
.poll { position: absolute; left: 5%; right: 5%; bottom: 5%; padding: 24px 30px 28px; border-radius: 26px; background: rgba(7,17,27,.96); border: 2px solid #ffffff24; box-shadow: 0 24px 70px #000b; }
|
|
11
|
+
.heading { display: flex; align-items: center; gap: 20px; margin-bottom: 18px; }
|
|
12
|
+
.eyebrow { flex: none; padding: 9px 16px; border-radius: 999px; background: var(--accent); color: #06151d; font-size: 19px; font-weight: 950; letter-spacing: .13em; }
|
|
13
|
+
.question { font-size: 38px; line-height: 1.12; font-weight: 850; text-wrap: balance; }
|
|
14
|
+
.options { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 18px; }
|
|
15
|
+
.option { position: relative; min-height: 65px; overflow: hidden; border-radius: 14px; background: #ffffff0c; border: 2px solid #ffffff18; }
|
|
16
|
+
.bar { position: absolute; inset: 0 auto 0 0; width: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 70%, #132e44), color-mix(in srgb, var(--accent) 30%, transparent)); transition: width .7s cubic-bezier(.2,.8,.2,1); }
|
|
17
|
+
.row { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; min-height: 61px; padding: 8px 17px; font-size: 26px; font-weight: 800; }
|
|
18
|
+
.percent { display: none; margin-left: 15px; color: white; font-size: 30px; font-weight: 950; font-variant-numeric: tabular-nums; }
|
|
19
|
+
.results .percent { display: block; }
|
|
20
|
+
.question-only .bar { width: 0 !important; }
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<section class="poll question-only" id="poll">
|
|
25
|
+
<div class="heading"><div class="eyebrow" id="eyebrow">AUDIENCE POLL</div><div class="question" id="question">Which destination should we visit next?</div></div>
|
|
26
|
+
<div class="options" id="options"></div>
|
|
27
|
+
</section>
|
|
28
|
+
<script>
|
|
29
|
+
const state = {
|
|
30
|
+
options: [{label: "Tokyo", votes: 420}, {label: "New York", votes: 310}, {label: "Barcelona", votes: 180}, {label: "Cape Town", votes: 90}],
|
|
31
|
+
display: "question"
|
|
32
|
+
};
|
|
33
|
+
function render() {
|
|
34
|
+
const container = document.getElementById("options");
|
|
35
|
+
const visibleOptions = state.options.slice(0, 4);
|
|
36
|
+
const totalVotes = visibleOptions.reduce((total, option) => total + Math.max(0, Number(option.votes) || 0), 0);
|
|
37
|
+
container.replaceChildren(...visibleOptions.map((option) => {
|
|
38
|
+
const item = document.createElement("div"); item.className = "option";
|
|
39
|
+
const votes = Math.max(0, Number(option.votes) || 0);
|
|
40
|
+
const percent = totalVotes > 0 ? Math.round(votes * 100 / totalVotes) : 0;
|
|
41
|
+
item.innerHTML = `<div class="bar" style="width:${percent}%"></div><div class="row"><span></span><strong class="percent">${percent}%</strong></div>`;
|
|
42
|
+
item.querySelector("span").textContent = option.label ?? "Option";
|
|
43
|
+
return item;
|
|
44
|
+
}));
|
|
45
|
+
const results = state.display === "results";
|
|
46
|
+
document.getElementById("poll").classList.toggle("results", results);
|
|
47
|
+
document.getElementById("poll").classList.toggle("question-only", !results);
|
|
48
|
+
}
|
|
49
|
+
window.addEventListener("nebular-overlay:update", ({detail = {}}) => {
|
|
50
|
+
if (Array.isArray(detail.options)) state.options = detail.options;
|
|
51
|
+
if (detail.control?.display != null) state.display = detail.control.display;
|
|
52
|
+
if (detail.content?.eyebrow != null) document.getElementById("eyebrow").textContent = detail.content.eyebrow;
|
|
53
|
+
if (detail.content?.question != null) document.getElementById("question").textContent = detail.content.question;
|
|
54
|
+
if (detail.style?.accent != null) document.body.style.setProperty("--accent", detail.style.accent);
|
|
55
|
+
render();
|
|
56
|
+
});
|
|
57
|
+
render();
|
|
58
|
+
</script>
|
|
59
|
+
</body>
|
|
60
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"instructions": "Build up to four poll options and enter their raw vote counts; percentages are calculated automatically. Keep Display on question while voting, then select results and press Update to reveal the animated outcome.",
|
|
3
|
+
"meta": {
|
|
4
|
+
"content/eyebrow": {"type": "string", "phase": "edit", "label": "Label", "hint": "Enter short label", "default": "AUDIENCE POLL"},
|
|
5
|
+
"content/question": {"type": "string", "phase": "edit", "label": "Question", "hint": "Enter question", "container": "big", "default": "Which destination should we visit next?"},
|
|
6
|
+
"options": {
|
|
7
|
+
"type": "set",
|
|
8
|
+
"label": "Poll options", "hint": "Answer choices and their current raw vote counts",
|
|
9
|
+
"max": 4,
|
|
10
|
+
"container": "big",
|
|
11
|
+
"default": [
|
|
12
|
+
{"label": "Tokyo", "votes": 420},
|
|
13
|
+
{"label": "New York", "votes": 310},
|
|
14
|
+
{"label": "Barcelona", "votes": 180},
|
|
15
|
+
{"label": "Cape Town", "votes": 90}
|
|
16
|
+
],
|
|
17
|
+
"meta": {
|
|
18
|
+
"label": {"type": "string", "phase": "edit", "label": "Option", "hint": "Enter option text"},
|
|
19
|
+
"staticlabel": {"type": "string", "phase": "play", "label": "Option", "hint": "Answer text displayed while voting", "source": "label", "readonly": true},
|
|
20
|
+
"votes": {"type": "number", "phase": "play", "label": "Votes", "hint": "Enter votes", "min": 0, "default": 0}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"control/display": {"type": "choose", "phase": "play", "label": "Display", "hint": "Choose whether viewers see the question or results", "choose": ["question", "results"], "default": "question"},
|
|
24
|
+
"style/accent": {"type": "color", "phase": "edit", "label": "Accent", "hint": "Accent colour used by the poll graphic", "default": "#36d1ff"}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Classic Quiz</title>
|
|
6
|
+
<style>
|
|
7
|
+
* { box-sizing: border-box; }
|
|
8
|
+
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: transparent; }
|
|
9
|
+
body { --accent: #ffb21c; color: #fff; font-family: Inter, Arial, sans-serif; }
|
|
10
|
+
.quiz { position: absolute; left: 4%; right: 4%; bottom: 4%; padding: 24px 28px 26px; border-radius: 24px; background: linear-gradient(135deg, rgba(13,16,29,.97), rgba(25,29,48,.95)); border: 2px solid #ffffff24; box-shadow: 0 20px 60px #0009; }
|
|
11
|
+
.top { display: flex; align-items: center; gap: 22px; margin-bottom: 18px; }
|
|
12
|
+
.badge { flex: none; padding: 10px 18px; border-radius: 999px; background: var(--accent); color: #17120a; font-size: 21px; font-weight: 900; letter-spacing: .12em; }
|
|
13
|
+
.question { font-size: 39px; line-height: 1.12; font-weight: 850; text-wrap: balance; }
|
|
14
|
+
.answers { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
|
15
|
+
.answer { display: flex; align-items: center; min-height: 68px; padding: 10px 18px; border: 2px solid #ffffff20; border-radius: 14px; background: #ffffff0b; font-size: 27px; font-weight: 750; transition: .35s ease; }
|
|
16
|
+
.letter { display: grid; place-items: center; width: 42px; height: 42px; margin-right: 14px; border-radius: 50%; background: #fff; color: #151827; font-size: 22px; font-weight: 950; }
|
|
17
|
+
.revealed .answer:not(.correct) { opacity: .32; }
|
|
18
|
+
.revealed .answer.correct { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 24%, #151827); transform: translateY(-2px); box-shadow: 0 0 28px color-mix(in srgb, var(--accent) 45%, transparent); }
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<section class="quiz" id="quiz">
|
|
23
|
+
<div class="top"><div class="badge" id="category">GENERAL KNOWLEDGE</div><div class="question" id="question">Which planet is known as the Red Planet?</div></div>
|
|
24
|
+
<div class="answers">
|
|
25
|
+
<div class="answer" data-answer="a"><span class="letter">A</span><span id="a">Venus</span></div>
|
|
26
|
+
<div class="answer" data-answer="b"><span class="letter">B</span><span id="b">Mars</span></div>
|
|
27
|
+
<div class="answer" data-answer="c"><span class="letter">C</span><span id="c">Jupiter</span></div>
|
|
28
|
+
<div class="answer" data-answer="d"><span class="letter">D</span><span id="d">Mercury</span></div>
|
|
29
|
+
</div>
|
|
30
|
+
</section>
|
|
31
|
+
<script>
|
|
32
|
+
const state = {correct: "b", display: "question"};
|
|
33
|
+
const text = (id, value) => { if (value != null) document.getElementById(id).textContent = value; };
|
|
34
|
+
function render() {
|
|
35
|
+
document.getElementById("quiz").classList.toggle("revealed", state.display === "answer");
|
|
36
|
+
document.querySelectorAll("[data-answer]").forEach(el => el.classList.toggle("correct", el.dataset.answer === state.correct));
|
|
37
|
+
}
|
|
38
|
+
window.addEventListener("nebular-overlay:update", ({detail = {}}) => {
|
|
39
|
+
text("category", detail.content?.category); text("question", detail.content?.question);
|
|
40
|
+
["a", "b", "c", "d"].forEach(key => text(key, detail.answers?.[key]));
|
|
41
|
+
if (detail.control?.correct != null) state.correct = detail.control.correct;
|
|
42
|
+
if (detail.control?.display != null) state.display = detail.control.display;
|
|
43
|
+
if (detail.style?.accent != null) document.body.style.setProperty("--accent", detail.style.accent);
|
|
44
|
+
render();
|
|
45
|
+
});
|
|
46
|
+
render();
|
|
47
|
+
</script>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"instructions": "Enter the category, question and four possible answers, then select the correct answer. Publish in question mode first; switch Display to answer and press Update when it is time to reveal the result.",
|
|
3
|
+
"meta": {
|
|
4
|
+
"content/category": {"type": "string", "phase": "edit", "label": "Category", "hint": "Enter category", "default": "GENERAL KNOWLEDGE"},
|
|
5
|
+
"content/question": {"type": "string", "phase": "edit", "label": "Question", "hint": "Enter question", "container": "big", "default": "Which planet is known as the Red Planet?"},
|
|
6
|
+
"answers/a": {"type": "string", "phase": "edit", "label": "Answer A", "hint": "Enter answer A", "default": "Venus"},
|
|
7
|
+
"answers/b": {"type": "string", "phase": "edit", "label": "Answer B", "hint": "Enter answer B", "default": "Mars"},
|
|
8
|
+
"answers/c": {"type": "string", "phase": "edit", "label": "Answer C", "hint": "Enter answer C", "default": "Jupiter"},
|
|
9
|
+
"answers/d": {"type": "string", "phase": "edit", "label": "Answer D", "hint": "Enter answer D", "default": "Mercury"},
|
|
10
|
+
"control/correct": {"type": "choose", "phase": "edit", "label": "Correct answer", "hint": "Answer revealed as correct", "choose": ["none", "a", "b", "c", "d"], "default": "b"},
|
|
11
|
+
"content/playQuestion": {"type": "string", "phase": "play", "label": "Question", "hint": "Question currently shown during play", "source": "content/question", "readonly": true},
|
|
12
|
+
"control/display": {"type": "choose", "phase": "play", "label": "Display", "hint": "Choose whether viewers see the question or the answer", "choose": ["question", "answer"], "default": "question"},
|
|
13
|
+
"style/accent": {"type": "color", "phase": "edit", "label": "Accent", "hint": "Accent colour used by the quiz graphic", "default": "#ffb21c"}
|
|
14
|
+
}
|
|
15
|
+
}
|