@ciphore/radiocli 0.2.1 → 0.2.3
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/CHANGELOG.md +133 -1
- package/README.md +76 -6
- package/dist/agent/alarm-service.js +210 -0
- package/dist/agent/cli.js +193 -0
- package/dist/agent/headless-host.js +143 -0
- package/dist/agent/launcher.js +71 -0
- package/dist/agent/mcp-install.js +467 -0
- package/dist/agent/mcp-server.js +139 -0
- package/dist/agent/service.js +347 -0
- package/dist/agent/session.js +248 -0
- package/dist/alarms/active-session.js +183 -0
- package/dist/alarms/cli.js +312 -0
- package/dist/alarms/guard.js +343 -0
- package/dist/alarms/inhibitor.js +48 -0
- package/dist/alarms/power-guard-store.js +169 -0
- package/dist/alarms/runner.js +342 -0
- package/dist/alarms/runtime-health.js +79 -0
- package/dist/alarms/schedule.js +149 -0
- package/dist/alarms/scheduler.js +250 -0
- package/dist/alarms/setup-verification.js +187 -0
- package/dist/alarms/system-volume.js +43 -0
- package/dist/alarms/terminal-launcher.js +181 -0
- package/dist/alarms/tui-presence.js +38 -0
- package/dist/cli.js +113 -5
- package/dist/player/backend-install.js +2 -1
- package/dist/player/command-diagnostics.js +27 -0
- package/dist/player/command.js +123 -62
- package/dist/player/player-controller.js +32 -2
- package/dist/providers/provider-manager.js +5 -0
- package/dist/providers/radio-browser.js +36 -6
- package/dist/setup.js +462 -0
- package/dist/storage/store.js +262 -2
- package/dist/types.js +6 -0
- package/dist/ui/AdaptiveContent.js +111 -26
- package/dist/ui/App.js +401 -67
- package/dist/ui/AppContent.js +24 -7
- package/dist/ui/adaptive-explore-layout.js +47 -0
- package/dist/ui/alarm-editor.js +174 -0
- package/dist/ui/alarm-tui-service.js +84 -0
- package/dist/ui/app-state.js +3 -0
- package/dist/ui/ascii.js +8 -0
- package/dist/ui/components/AdaptiveMarquee.js +28 -0
- package/dist/ui/components/StationList.js +10 -5
- package/dist/ui/components/VersionIndicator.js +19 -0
- package/dist/ui/cosmo-world-map.js +5 -2
- package/dist/ui/explore-map-layout.js +18 -6
- package/dist/ui/format.js +21 -0
- package/dist/ui/help-content.js +14 -2
- package/dist/ui/layout.js +1 -1
- package/dist/ui/page-footer.js +120 -2
- package/dist/ui/receiver-animation.js +68 -0
- package/dist/ui/screen-items.js +41 -9
- package/dist/ui/screen-meta.js +4 -0
- package/dist/ui/screens/AlarmsScreen.js +202 -0
- package/dist/ui/screens/CountriesScreen.js +8 -5
- package/dist/ui/screens/ExploreScreen.js +8 -3
- package/dist/ui/screens/HomeScreen.js +3 -1
- package/dist/ui/screens/NowPlayingScreen.js +6 -2
- package/dist/ui/screens/SettingsScreen.js +70 -53
- package/dist/ui/screens/StationScreen.js +3 -2
- package/dist/ui/selection-state.js +10 -0
- package/dist/ui/terminal-mouse.js +18 -3
- package/dist/ui/use-alarm-tui.js +727 -0
- package/dist/ui/use-app-input.js +107 -46
- package/dist/ui/visualizers/gallop.js +118 -0
- package/dist/ui/visualizers/horse-stride.js +20 -0
- package/dist/ui/visualizers/receiver-style-registry.js +14 -7
- package/dist/ui/visualizers/receiver-visualizers.js +233 -128
- package/dist/ui/visualizers/retro-receivers.js +4 -0
- package/dist/ui/visualizers/terminal-receivers.js +57 -0
- package/dist/update-check.js +26 -7
- package/package.json +6 -1
package/dist/ui/use-app-input.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { useInput } from 'ink';
|
|
3
|
-
import { homeItems,
|
|
4
|
-
import { applyTextInput,
|
|
3
|
+
import { homeItems, settingsItemsForPage, settingsPageForRootItem } from './screen-items.js';
|
|
4
|
+
import { applyTextInput, favoriteTarget, isEditableInput, isPlainPrintableInput, mediaTransportActionForInput, searchEditingArrowAction, shouldHandleKeyboardEvent, shouldToggleNearbyLocationShortcut } from './app-state.js';
|
|
5
5
|
import { parseTerminalMouseEvents, primaryMousePress, wheelScrollDelta } from './terminal-mouse.js';
|
|
6
6
|
import { completeCommand } from './help-content.js';
|
|
7
|
-
|
|
7
|
+
import { commitImmediateSelection } from './selection-state.js';
|
|
8
|
+
export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, cancelPendingAutoSkip, beginLearningTransportKey, capturingTransportAction, commandMode, commandText, confirmCtrlCExit, copyStationUrl, openStationHomepage, currentItemCount, cycleDisplayColor, cycleAudioOutput, cycleReceiverStyle, cycleSleepTimer, editingCountryFilter, editingSearch, executeCommand, filteredCountries, go, lastRawTransportAtRef, lastSubmittedSearchRef, loadCountry, openAdjacentTab, openAirPlayCode, openAirPlaySettings, openSettingsPage, closeSettingsPage, openScreen, handleAlarmInput, openAlarmForStation, openActiveAlarms, playAdjacent, playStation, player, playingStation, recallSearchHistory, moveExploreCursor, moveExploreCursorToCell, refreshAirPlayTargets, refreshProviderHealth, resetLearnedTransportKeys, repairMcpIntegrations, setAgentIntegrationEnabled, runSearch, saveLearnedTransportKey, screen, settingsPage, searchQuery, selectedRef, selectedStationForInput, selectAirPlayDeviceAt, setCapturingTransportAction, setAirPlayCode, setCommandMode, setCommandText, setCountryFilter, setEditingCountryFilter, setEditingSearch, setMessage, setSearchQuery, setSelected, setShowDiagnostics, submitAirPlayCode, settingsRef, shutdown, stdin, toggleFavorite, toggleMute, togglePause, toggleSetting, toggleAgentSetting, toggleNearbyLocation, toggleDirectoryVoting, toggleRadioGarden, toggleSkipBrokenStreams, updateFromSettings }) {
|
|
9
|
+
const commitSelection = (next) => {
|
|
10
|
+
commitImmediateSelection(selectedRef, setSelected, next, currentItemCount(screen));
|
|
11
|
+
};
|
|
12
|
+
const moveSelection = (delta) => {
|
|
13
|
+
if (hasStationSelection(screen))
|
|
14
|
+
cancelPendingAutoSkip();
|
|
15
|
+
commitSelection(selectedRef.current + delta);
|
|
16
|
+
};
|
|
8
17
|
useEffect(() => {
|
|
9
18
|
const onData = (data) => {
|
|
10
19
|
const rawInput = String(data);
|
|
@@ -26,7 +35,9 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
26
35
|
const click = primaryMousePress(mouseEvents);
|
|
27
36
|
lastRawTransportAtRef.current = Date.now();
|
|
28
37
|
if (wheelDelta !== 0 && shouldScrollSelectionWithWheel(screen, commandMode, editingCountryFilter)) {
|
|
29
|
-
|
|
38
|
+
if (handleAlarmInput('', { scrollDelta: wheelDelta * 3 }))
|
|
39
|
+
return;
|
|
40
|
+
moveSelection(wheelDelta * 3);
|
|
30
41
|
return;
|
|
31
42
|
}
|
|
32
43
|
if (!commandMode && screen === 'explore' && click) {
|
|
@@ -57,18 +68,23 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
57
68
|
stdin.off('data', onData);
|
|
58
69
|
};
|
|
59
70
|
}, [
|
|
71
|
+
cancelPendingAutoSkip,
|
|
60
72
|
capturingTransportAction,
|
|
61
73
|
commandMode,
|
|
74
|
+
currentItemCount,
|
|
62
75
|
editingCountryFilter,
|
|
63
76
|
editingSearch,
|
|
77
|
+
handleAlarmInput,
|
|
64
78
|
lastRawTransportAtRef,
|
|
65
79
|
playAdjacent,
|
|
66
80
|
player,
|
|
67
81
|
moveExploreCursorToCell,
|
|
68
82
|
saveLearnedTransportKey,
|
|
69
83
|
screen,
|
|
84
|
+
selectedRef,
|
|
70
85
|
setCapturingTransportAction,
|
|
71
86
|
setMessage,
|
|
87
|
+
setSelected,
|
|
72
88
|
settingsRef,
|
|
73
89
|
stdin,
|
|
74
90
|
togglePause
|
|
@@ -109,30 +125,17 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
109
125
|
}
|
|
110
126
|
return;
|
|
111
127
|
}
|
|
112
|
-
if (
|
|
113
|
-
playAdjacent(-1);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (key.shift && key.rightArrow) {
|
|
117
|
-
playAdjacent(1);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
if (key.tab) {
|
|
121
|
-
openAdjacentTab(key.shift ? -1 : 1);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (key.rightArrow) {
|
|
125
|
-
openAdjacentTab(1);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
if (key.leftArrow) {
|
|
129
|
-
openAdjacentTab(-1);
|
|
128
|
+
if (handleAlarmInput(input, key)) {
|
|
130
129
|
return;
|
|
131
130
|
}
|
|
131
|
+
// An active text field owns its keystrokes before app-wide shortcuts. In
|
|
132
|
+
// particular, a normal "a" in a station query must not invoke the global
|
|
133
|
+
// schedule-this-station shortcut and leave Search for the alarm editor.
|
|
132
134
|
if (screen === 'search' && editingSearch) {
|
|
133
135
|
if (key.return) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
const inputStation = selectedStationForInput();
|
|
137
|
+
if (searchQuery.trim() && searchQuery.trim() === lastSubmittedSearchRef.current && inputStation) {
|
|
138
|
+
void playStation(inputStation);
|
|
136
139
|
}
|
|
137
140
|
else {
|
|
138
141
|
void runSearch();
|
|
@@ -152,10 +155,10 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
152
155
|
recallSearchHistory('newer');
|
|
153
156
|
}
|
|
154
157
|
else if (arrowAction === 'select-previous') {
|
|
155
|
-
|
|
158
|
+
moveSelection(-1);
|
|
156
159
|
}
|
|
157
160
|
else {
|
|
158
|
-
|
|
161
|
+
moveSelection(1);
|
|
159
162
|
}
|
|
160
163
|
return;
|
|
161
164
|
}
|
|
@@ -165,10 +168,38 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
165
168
|
return;
|
|
166
169
|
}
|
|
167
170
|
}
|
|
171
|
+
if (input === '!' || (input === 'A' && screen !== 'explore')) {
|
|
172
|
+
openActiveAlarms();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (input === 'a' && ['stations', 'search', 'nearby', 'library', 'now-playing'].includes(screen)) {
|
|
176
|
+
openAlarmForStation(favoriteTarget(screen, selectedStationForInput(), playingStation));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (key.shift && key.leftArrow) {
|
|
180
|
+
playAdjacent(-1);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (key.shift && key.rightArrow) {
|
|
184
|
+
playAdjacent(1);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (key.tab) {
|
|
188
|
+
openAdjacentTab(key.shift ? -1 : 1);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (key.rightArrow) {
|
|
192
|
+
openAdjacentTab(1);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (key.leftArrow) {
|
|
196
|
+
openAdjacentTab(-1);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
168
199
|
if ((screen === 'countries' || screen === 'map') && editingCountryFilter) {
|
|
169
200
|
if (key.return || key.escape) {
|
|
170
201
|
setEditingCountryFilter(false);
|
|
171
|
-
|
|
202
|
+
commitSelection(0);
|
|
172
203
|
return;
|
|
173
204
|
}
|
|
174
205
|
if (isEditableInput(input, key)) {
|
|
@@ -287,16 +318,16 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
287
318
|
return;
|
|
288
319
|
}
|
|
289
320
|
if (input === ']') {
|
|
290
|
-
|
|
321
|
+
moveSelection(10);
|
|
291
322
|
return;
|
|
292
323
|
}
|
|
293
324
|
if (input === '[') {
|
|
294
|
-
|
|
325
|
+
moveSelection(-10);
|
|
295
326
|
return;
|
|
296
327
|
}
|
|
297
|
-
if (screen === 'home' && /^[1-
|
|
328
|
+
if (screen === 'home' && /^[1-9]$/.test(input)) {
|
|
298
329
|
const menuIndex = Number(input) - 1;
|
|
299
|
-
|
|
330
|
+
commitSelection(menuIndex);
|
|
300
331
|
const target = homeItems[menuIndex]?.screen;
|
|
301
332
|
if (target) {
|
|
302
333
|
openScreen(target);
|
|
@@ -307,6 +338,10 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
307
338
|
go('settings');
|
|
308
339
|
return;
|
|
309
340
|
}
|
|
341
|
+
if ((input === 'b' || key.escape) && screen === 'settings') {
|
|
342
|
+
closeSettingsPage();
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
310
345
|
if (input === 'b' || key.escape) {
|
|
311
346
|
if (screen === 'stations') {
|
|
312
347
|
go('countries');
|
|
@@ -333,15 +368,15 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
333
368
|
return;
|
|
334
369
|
}
|
|
335
370
|
if (input === 'f') {
|
|
336
|
-
toggleFavorite(favoriteTarget(screen,
|
|
371
|
+
toggleFavorite(favoriteTarget(screen, selectedStationForInput(), playingStation));
|
|
337
372
|
return;
|
|
338
373
|
}
|
|
339
374
|
if (input === 'O') {
|
|
340
|
-
openStationHomepage(favoriteTarget(screen,
|
|
375
|
+
openStationHomepage(favoriteTarget(screen, selectedStationForInput(), playingStation));
|
|
341
376
|
return;
|
|
342
377
|
}
|
|
343
378
|
if (input === 'y') {
|
|
344
|
-
void copyStationUrl(favoriteTarget(screen,
|
|
379
|
+
void copyStationUrl(favoriteTarget(screen, selectedStationForInput(), playingStation));
|
|
345
380
|
return;
|
|
346
381
|
}
|
|
347
382
|
if (input === ' ') {
|
|
@@ -357,38 +392,45 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
357
392
|
return;
|
|
358
393
|
}
|
|
359
394
|
if (input === 'n') {
|
|
360
|
-
|
|
395
|
+
moveSelection(1);
|
|
361
396
|
return;
|
|
362
397
|
}
|
|
363
398
|
if (input === 'p') {
|
|
364
|
-
|
|
399
|
+
moveSelection(-1);
|
|
365
400
|
return;
|
|
366
401
|
}
|
|
367
402
|
if (key.downArrow) {
|
|
368
|
-
|
|
403
|
+
moveSelection(1);
|
|
369
404
|
return;
|
|
370
405
|
}
|
|
371
406
|
if (key.upArrow) {
|
|
372
|
-
|
|
407
|
+
moveSelection(-1);
|
|
373
408
|
return;
|
|
374
409
|
}
|
|
375
410
|
if (key.return) {
|
|
376
411
|
if (screen === 'home') {
|
|
377
|
-
const target = homeItems[
|
|
412
|
+
const target = homeItems[selectedRef.current]?.screen;
|
|
378
413
|
if (target) {
|
|
379
414
|
openScreen(target);
|
|
380
415
|
}
|
|
381
416
|
return;
|
|
382
417
|
}
|
|
383
418
|
if (screen === 'countries') {
|
|
384
|
-
const country = filteredCountries[
|
|
419
|
+
const country = filteredCountries[selectedRef.current];
|
|
385
420
|
if (country) {
|
|
386
421
|
void loadCountry(country);
|
|
387
422
|
}
|
|
388
423
|
return;
|
|
389
424
|
}
|
|
390
425
|
if (screen === 'settings') {
|
|
391
|
-
const item =
|
|
426
|
+
const item = settingsItemsForPage(settingsPage)[selectedRef.current];
|
|
427
|
+
if (settingsPage === 'root') {
|
|
428
|
+
const targetPage = settingsPageForRootItem(item);
|
|
429
|
+
if (targetPage) {
|
|
430
|
+
openSettingsPage(targetPage);
|
|
431
|
+
}
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
392
434
|
if (item === 'Cycle display color') {
|
|
393
435
|
cycleDisplayColor();
|
|
394
436
|
}
|
|
@@ -437,6 +479,21 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
437
479
|
else if (item === 'Mouse and trackpad scrolling') {
|
|
438
480
|
toggleSetting('mouseSupport');
|
|
439
481
|
}
|
|
482
|
+
else if (item === 'Automatically check for updates') {
|
|
483
|
+
toggleSetting('automaticUpdateChecks');
|
|
484
|
+
}
|
|
485
|
+
else if (item === 'Allow local agent control') {
|
|
486
|
+
void setAgentIntegrationEnabled();
|
|
487
|
+
}
|
|
488
|
+
else if (item === 'Install or repair MCP integrations') {
|
|
489
|
+
void repairMcpIntegrations();
|
|
490
|
+
}
|
|
491
|
+
else if (item === 'Open TUI for agent playback') {
|
|
492
|
+
toggleAgentSetting('openUiOnPlay');
|
|
493
|
+
}
|
|
494
|
+
else if (item === 'Show Now Playing for agent playback') {
|
|
495
|
+
toggleAgentSetting('focusNowPlaying');
|
|
496
|
+
}
|
|
440
497
|
else if (item === 'Export preferences and library') {
|
|
441
498
|
setCommandText('export ');
|
|
442
499
|
setCommandMode(true);
|
|
@@ -467,18 +524,19 @@ export function useAppInput({ adjustVolume, airPlayCode, canEnterAirPlayCode, be
|
|
|
467
524
|
return;
|
|
468
525
|
}
|
|
469
526
|
if (screen === 'airplay-settings') {
|
|
470
|
-
selectAirPlayDeviceAt(
|
|
527
|
+
selectAirPlayDeviceAt(selectedRef.current);
|
|
471
528
|
return;
|
|
472
529
|
}
|
|
473
530
|
if (screen === 'map') {
|
|
474
|
-
const country = filteredCountries[
|
|
531
|
+
const country = filteredCountries[selectedRef.current];
|
|
475
532
|
if (country) {
|
|
476
533
|
void loadCountry(country);
|
|
477
534
|
}
|
|
478
535
|
return;
|
|
479
536
|
}
|
|
480
|
-
|
|
481
|
-
|
|
537
|
+
const inputStation = selectedStationForInput();
|
|
538
|
+
if (inputStation) {
|
|
539
|
+
void playStation(inputStation);
|
|
482
540
|
}
|
|
483
541
|
}
|
|
484
542
|
});
|
|
@@ -489,9 +547,12 @@ function shouldScrollSelectionWithWheel(screen, commandMode, editingCountryFilte
|
|
|
489
547
|
}
|
|
490
548
|
return [
|
|
491
549
|
'home', 'countries', 'map', 'stations', 'search', 'nearby', 'explore',
|
|
492
|
-
'library', 'settings', 'help', 'airplay-settings'
|
|
550
|
+
'library', 'settings', 'help', 'airplay-settings', 'alarms', 'alarm-editor', 'alarm-picker', 'alarm-ringing'
|
|
493
551
|
].includes(screen);
|
|
494
552
|
}
|
|
553
|
+
function hasStationSelection(screen) {
|
|
554
|
+
return ['stations', 'search', 'nearby', 'explore', 'library'].includes(screen);
|
|
555
|
+
}
|
|
495
556
|
function exploreMoveForInput(input) {
|
|
496
557
|
const normalized = input.toLowerCase();
|
|
497
558
|
if (normalized === 'w') {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { themeAccent } from '../theme.js';
|
|
2
|
+
import { horseStrideFrames, horseStrideHeight, horseStrideWidth } from './horse-stride.js';
|
|
3
|
+
const frames = horseStrideFrames.map(frame => Buffer.from(frame, 'base64'));
|
|
4
|
+
const brailleBits = [[1, 8], [2, 16], [4, 32], [64, 128]];
|
|
5
|
+
/** One pose per receiver tick. The same scale and torso anchor are used for every pose. */
|
|
6
|
+
export function buildGallop(pulse, width, height, theme) {
|
|
7
|
+
const w = Math.max(1, Math.floor(width));
|
|
8
|
+
const h = Math.max(1, Math.floor(height));
|
|
9
|
+
const color = themeAccent(theme);
|
|
10
|
+
const frameIndex = ((Math.floor(pulse) % frames.length) + frames.length) % frames.length;
|
|
11
|
+
const frame = frames[frameIndex];
|
|
12
|
+
const usableW = w > 8 ? w - 4 : w;
|
|
13
|
+
const usableH = h > 4 ? h - 2 : h;
|
|
14
|
+
const scale = Math.min(usableW * 2 / horseStrideWidth, usableH * 4 / horseStrideHeight);
|
|
15
|
+
const dotsW = Math.max(1, Math.floor(horseStrideWidth * scale));
|
|
16
|
+
const dotsH = Math.max(1, Math.floor(horseStrideHeight * scale));
|
|
17
|
+
const left = Math.floor((w - Math.ceil(dotsW / 2)) / 2) * 2;
|
|
18
|
+
const top = Math.floor((h - Math.ceil(dotsH / 4)) / 2) * 4;
|
|
19
|
+
const masks = new Uint8Array(w * h);
|
|
20
|
+
for (let y = 0; y < dotsH; y++) {
|
|
21
|
+
const sy0 = Math.floor(y * horseStrideHeight / dotsH);
|
|
22
|
+
const sy1 = Math.ceil((y + 1) * horseStrideHeight / dotsH);
|
|
23
|
+
for (let x = 0; x < dotsW; x++) {
|
|
24
|
+
const sx0 = Math.floor(x * horseStrideWidth / dotsW);
|
|
25
|
+
const sx1 = Math.ceil((x + 1) * horseStrideWidth / dotsW);
|
|
26
|
+
let ink = 0;
|
|
27
|
+
for (let sy = sy0; sy < sy1; sy++)
|
|
28
|
+
for (let sx = sx0; sx < sx1; sx++) {
|
|
29
|
+
const bit = sy * horseStrideWidth + sx;
|
|
30
|
+
ink += (frame[bit >> 3] >> (bit & 7)) & 1;
|
|
31
|
+
}
|
|
32
|
+
// Area coverage keeps thin legs continuous as the terminal becomes smaller.
|
|
33
|
+
if (ink / ((sx1 - sx0) * (sy1 - sy0)) < 0.22)
|
|
34
|
+
continue;
|
|
35
|
+
const dx = left + x;
|
|
36
|
+
const dy = top + y;
|
|
37
|
+
const index = Math.floor(dy / 4) * w + Math.floor(dx / 2);
|
|
38
|
+
masks[index] |= brailleBits[dy % 4][dx % 2];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return Array.from({ length: h }, (_, y) => {
|
|
42
|
+
let text = '';
|
|
43
|
+
for (let x = 0; x < w; x++) {
|
|
44
|
+
const mask = masks[y * w + x];
|
|
45
|
+
text += mask === 0 ? ' ' : String.fromCharCode(0x2800 + mask);
|
|
46
|
+
}
|
|
47
|
+
// No background color: only the horse's ink is drawn over the receiver panel.
|
|
48
|
+
return { text, color, segments: [{ text, color }] };
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Lightly pare back thick stroke edges, keeping endpoints and junctions intact. */
|
|
52
|
+
export function buildGallopFine(pulse, width, height, theme) {
|
|
53
|
+
return thinGallopStrokes(buildGallop(pulse, width, height, theme), 0.14);
|
|
54
|
+
}
|
|
55
|
+
function thinGallopStrokes(original, reduction) {
|
|
56
|
+
const w = original[0].text.length;
|
|
57
|
+
const h = original.length;
|
|
58
|
+
const dw = w * 2;
|
|
59
|
+
const dh = h * 4;
|
|
60
|
+
const dots = new Uint8Array(dw * dh);
|
|
61
|
+
let inkCount = 0;
|
|
62
|
+
original.forEach((row, y) => {
|
|
63
|
+
[...row.text].forEach((glyph, x) => {
|
|
64
|
+
const mask = glyph === ' ' ? 0 : glyph.charCodeAt(0) - 0x2800;
|
|
65
|
+
for (let yy = 0; yy < 4; yy++)
|
|
66
|
+
for (let xx = 0; xx < 2; xx++) {
|
|
67
|
+
if (mask & brailleBits[yy][xx]) {
|
|
68
|
+
dots[(y * 4 + yy) * dw + x * 2 + xx] = 1;
|
|
69
|
+
inkCount++;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
const neighbors = [-dw, -dw + 1, 1, dw + 1, dw, dw - 1, -1, -dw - 1];
|
|
75
|
+
const canThin = (index) => {
|
|
76
|
+
if (!dots[index])
|
|
77
|
+
return false;
|
|
78
|
+
const ring = neighbors.map(offset => dots[index + offset]);
|
|
79
|
+
const count = ring.reduce((total, dot) => total + dot, 0);
|
|
80
|
+
// Already-fine lines and endpoints stay untouched. A single connected arc of
|
|
81
|
+
// neighbors ensures removing this edge dot cannot split a leg or contour.
|
|
82
|
+
if (count < 3 || count > 6)
|
|
83
|
+
return false;
|
|
84
|
+
let transitions = 0;
|
|
85
|
+
for (let i = 0; i < 8; i++)
|
|
86
|
+
if (!ring[i] && ring[(i + 1) % 8])
|
|
87
|
+
transitions++;
|
|
88
|
+
return transitions === 1;
|
|
89
|
+
};
|
|
90
|
+
const candidates = [];
|
|
91
|
+
for (let y = 1; y < dh - 1; y++)
|
|
92
|
+
for (let x = 1; x < dw - 1; x++) {
|
|
93
|
+
const index = y * dw + x;
|
|
94
|
+
if (canThin(index))
|
|
95
|
+
candidates.push(index);
|
|
96
|
+
}
|
|
97
|
+
const budget = Math.min(candidates.length, Math.floor(inkCount * reduction));
|
|
98
|
+
for (let i = 0; i < budget; i++) {
|
|
99
|
+
// Spread the small reduction over the entire horse instead of thinning its
|
|
100
|
+
// head first. Recheck after each removal to preserve connected strokes.
|
|
101
|
+
const index = candidates[Math.floor(i * candidates.length / budget)];
|
|
102
|
+
if (canThin(index))
|
|
103
|
+
dots[index] = 0;
|
|
104
|
+
}
|
|
105
|
+
return original.map((row, y) => {
|
|
106
|
+
let text = '';
|
|
107
|
+
for (let x = 0; x < w; x++) {
|
|
108
|
+
let mask = 0;
|
|
109
|
+
for (let yy = 0; yy < 4; yy++)
|
|
110
|
+
for (let xx = 0; xx < 2; xx++) {
|
|
111
|
+
if (dots[(y * 4 + yy) * dw + x * 2 + xx])
|
|
112
|
+
mask |= brailleBits[yy][xx];
|
|
113
|
+
}
|
|
114
|
+
text += mask ? String.fromCharCode(0x2800 + mask) : ' ';
|
|
115
|
+
}
|
|
116
|
+
return { text, color: row.color, segments: [{ text, color: row.color }] };
|
|
117
|
+
});
|
|
118
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Fixed-canvas gallop poses derived from the user-provided horse line-art reference.
|
|
2
|
+
* Each base64 frame is a 128 × 80 one-bit ink mask, packed least-significant bit first.
|
|
3
|
+
* Background pixels are transparent; no video decoder or source file is needed at runtime.
|
|
4
|
+
*/
|
|
5
|
+
export const horseStrideWidth = 128;
|
|
6
|
+
export const horseStrideHeight = 80;
|
|
7
|
+
export const horseStrideFrames = [
|
|
8
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAOB9AAAAAAAAAAAAAAAAAADwMQAAAAAAAAAAAAAAAAAADzADAAAAAAAAAAAAAAAAwA8mBwAAAAAAAAAAAAAAAPCAAxwAAAAAAAAAAAAAAAA4wAE4AAAAAAAAAAAAAAAAmGcAcAAAAAAAAAAAAAAAAIg5APgAAAAAAAAAAAAAAAAMOGCAAQAAAAAAAAAAAAAABgxgIAMAAAAAAAAAAAAAgAMGYAAIAAAAAAAAAAAAAMABA2AAGAAAAAAAAAAAAADgxwPAABAAAAAAAAAAAAAA8OMA4A8QAAAAAAAAAAAAAPB8AGB+EAAAAAAAAAAAAADgHgAw4BAAAAAAAAAAAAAAwAcAEIARAAAAAAAAAID/AcABABgAAQAAAAAAAADw//9hgAAYAAAAAAAAAAAAeAD8AQABDAAAAAAAAAAAAB4AAAAAAAwAAAAAAAAAAAAHEAAAAAAMAAAAAAAAAACAAxAAAAAGDAAAAAAAAAAAgAEAAAAADAYAAAAAAAAAADgAAAAAABgGAAAAAAAAAMAfAAAAAAA4BgAAAAAAAAD/AwAAAAAAMAIAAAAAAADg/wMAAAAAAHAHAAAAAAAAMIBgAAAAAADwBwAAAAAAAAjwYADAAAAA8AcAAAAAAAAAOOAAwAAAAPAGAAAAAAAAAAjAEMAAAAD4DgAAAAAAAAAIwHGAAAAA/DwAAAAAAAAAAIBDgAAAAPwgAAAAAAAAAAAAB4AAAAB9AA8AAAAABgAAAB+AAACCfQAeAAAA5gwAAAB+gAAAxngAGAAAAIwBgAAA+MADAObw/zEAAAAYAIAAALCB/wB+YK8HAAAAcADAAADggf//f+AADgAAAMABYAAA4IP5f/DEAQwAAAAAPnAAAECDAQDAhwMYAAAAAD84AABAhgEAAB8HGAAAAIAfHwAAwIYAAAB8DtAAAAAA/QcAAMCGAAAA8BzQAAAAAPABAACAhAEAAMABsAEAAAAAAAAAgIYBAEyACbABAAAAAAAAAIAGAYDPwAlwAQAAAAAAAADAHgOA8/kAcAMAAAAAAAAAwD4cANt/APADAAAAAAAAAGD4+AC4PgDgAwAAAAAAAAAAwOcDcD4AwAMAAAAAAAAAwACfD+APAOAGAAAAAAAAAIACOAzgBwDgBwAAAAAAAAAAAuAYwAAAQAcAAAAAAAAAADbAOQAAAMAAAAAAAAAAAABmAHMAAADABQAAAAAAAAAAbADBAAAAAAcAAAAAAAAAANgAhwAAAAAGAAAAAAAAAACYAA4AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAACACAAAAAAAAAAAAAAAAAABgAgAAAAAAAAAAAAAAAAAAYAYAAAAAAAAAAAAAAAAAAEAdAAAAAAAAAAAAAAAAAACANwAAAAAAAAAAAAAAAAAAgGMAAAAAAAAAAAAAAAAA4P//AwAAAAAAAAAAAAAAAOD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
9
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAACA/wAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAAAAAAABgBgAAAAAAAAAAAAAAAAAA7BwAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAYA4AAAAAAAAAAAAAAAAABAAOABAAAAAAAAAAAAAABgMABwAwAAAAAAAAAAAABAABjAAAYAAAAAAAAAAAAAAAAMwMAMAAAAAAAAAAAAAAAAAMAAGAAAAAAAAAAAAAAAAADAADAAAAAAAAAAAAAAAMAAwAMgAAAAAAAAAAAAABx4AIB/YAAAAAAAAAAAAAAEHACA4GEAAAAAAAAAAAAAAAcAAIBjAAAAAAAAAAAAAIABAAAAQgAAAAAAAACA/wHAAAAAAAAAAAAAAAAAAMD/XwAAEAAAAAAAAAAAAAYA/AMAAhAAAAAAAAAAAIADAAAAAAYYAAAAAAAAAACAAQAAAAAMCAAAAAAAAAAA4AAAAAAADAwAAAAAAAAAAHwAAAAAABgMAAAAAAAAAAAeACAAAAAQBAAAAAAAAAAAGABgAAAAAAYAAAAAAAAAADgAYAAAAAACAAAAAAAAAAAAAEAAAAAAAwAAAAAAAAwAYADAAAAAgAcAAAAAAAAAAGAAwAAAAKAEAAAAAAAAAADAAIAAAAAgAAAAAAAAAAAA4AGAAAAAwAAAAAAAAAAAAKADgAEAA0AAAAAAAAAAAABgDwAAAAKAQAAAAAAAAAAAYB8AAAAG4EAAAAAAOAAAAMB4AAEABOEADwAAAPABAAHA8QMDAIzAAR4AAADAi4ABgIEDHwDMADwwAAAAwMDAAAADA///D3z8YAAAAIB5wAAAAwbi//vxuQMAAAAAH2AAAAMMAgDAf2AOAAAAAAAwAAADGwYAAPhjOAAAAMACHAAAgxkGAAAAR7ADAADA/w8AgIExBgAAAExgAwAAAP8HAIDBMAQAAAAMwAYAAAA8AADAcSAMAAAABIAMAAAAAAAA8DmwDAAAABaAGQAAAAAAAPAYsBkAAAAbgBkAAAAAAADwDKA3AACAG4ARAAAAAAAA4AzgcAAAxA2AOwAAAAAAAGAMgOMAgPUGAH8AAAAAAABgBgDPAeAfBgDsAAAAAAAAwAQAnAfwDQMAiAAAAAAAAMAEAHAOsI0BAPwBAAAAAADADADgHPC/AQCcAQAAAAAAgAwAwDkAMAAAOAMAAAAAAIANAIAzAAAAAPADAAAAAACAGQAAdwAAAACAAgAAAAAAgBkAAOwAAAAAAAAAAAAAAIA5AADuAQAAAAAAAAAAAACAOwAAvgMAAAAAAAAAAAAAwD8AAPwHAAAAAAAAAAAAAAA/AAD4BwAAAAAAAAAAAAAAfQAAAAAAAAAAAAAAAAAAAO4AAAAAAAAAAAAAAAAAAACEAQAAAAAAAAAAAAAAAAAA/AMAAAAAAAAAAAAAAAAAAPgDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
10
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAAeAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAwMwAAAAAAAAAAAAAAAAAAPjNAQAAAAAAAAAAAAAAAAAcAAMAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAYAAADAAAAAAAAAAAAABAhjgACB4AAAAAAAAAAAAAcBAcAAwwAAAAAAAAAAAAAAAABwAMbAAAAAAAAAAAAAAA4AMADIAAAAAAAAAAAAAAAHgAAAyAAQAAAAAAAAAAAAAOAAAcAAMAAAAAAAAAAACAAwAA/gECAAAAAAAA8B8A4AEBAOQHAgAAAAAAAP7/D34AAwAAHgIAAAAAAIAPAA8PAAYAADgCAAAAAADAAQAAAAAEAAAQAgAAAAAAcAAAAAAAECAAAAAAAAAAAD4AAAAAABAwAAAAAAAAAIAfAAAAAAAAGAAAAAAAAACADwAAAAAAAAwAAAAAAAAAgA8AAAAAAAAMAAAAAAAAAAAEAAAAAAAABgAAAAAAAAAADgAAAAAAgAMAAAAAAAAAABoAAAAAAIACAAAAAAAAAAAbABAAAACAAgAAAAAAAAAAGwAQAAAAwAIAAAAAAAAAADEAEAAAAMACAAAAAAAAAIAxABAAAAAAAgAAAAAAAACAYQAYAAAM4AIAAAAAAAAQgOEAGAAAAMAHAAAAAAAACIDBAQgAAAAGBwAAAAAAAAyAAAd4AAAcAgwAAAAA4AAEwAAE/AMAPAL8AAAAAMADBuAABow/gH/44AAAAAAAA0NwwAUE8P/nTwABAAAAAABhPOAEBgAAgP8fBgAAAAAMYB5wBgMAAADAPwYAAAAACLgfOAYDAAAAgHMAAAAAADjPBx6GAQAAAADnAAAAAADnR0EHwwAAAAAAjAQAAAAA/mDxgeMAAAAAAJwEAAAAAACgeMBhAAAAAACYDQAAAAAAMB7gMQAAAAAA8A0AAAAAABgHYBEAAAAAAOANAAAAAACYA+ARAAAAAACACQAAAAAA4AHAEQAAAAAAADkAAAAAAHcAgAEAAAAAAAD4AAAAAPA7AIAzAAAAAACAiQEAAAD0HAAANgAAAAAAgAkDAAAAHw4AAGYAAAAAAMAPHgAAgAkHAADsAAAAAADA/XwAAMCgAwAA3AAAAAAA4P/5AQBg/AEAAJgBAAAAAGCHjwMAcHwAAACYAwAAAABABjcAAPAHAAAAMAcAAAAAwAIwAADAAAAAAHAGAAAAAIADAAAAAAAAAABwDgAAAACAAQAAAAAAAAAAwB8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAYwAAAAAAAAAAAAAAAAAAgP8AAAAAAAAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
11
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwH8AAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAA8H8DAAAAAAAAAAAAAAAAAH4ABwAAAAAAAAAAAAAAAIAPAAwAAAAAAAAAAAAAAATgAQAYAAAAAAAAAAAAAAAAPAAAMAAAAAAAAAAAAAAAAA8AIHgAAAAAAAAAAAAAAMADACDYAAAAAAAAAAAAAAD+AAAwkAEAAAAAAAAAAACADwAAOBADAAAAAAAAAAAAwAMAADgAAwAAAAAAAPwfAPABAABwAAYAAAAAAID/////AAAA/AMMAAAAAADAB4A/AAAAAAEPAAAAAAAA4AEAAAAADMABOAwAAAAAAH8AAAAAAADgAHAMAAAAAOAfAAAAAABgMABADAAAAIC7DwAAAAAAQBgAAAAAAADgzQ8AAAAAAMAcAAAAAAAA8AAOAAAAAACADwAAAAAAAHgADgAAAAAAgAcAAAAAAAA4AA4AAAAAAAADAAAAAAAACAAOAAAAAACAAQAAAAAAAAAADgAIAAAAgAEAAAAAAAAAAB4ADAAACIABAAAAAAAAAAAeAAwAAAiAAQAAAAAAAAAAvgAMAAAIgAEAAAAAAAAAAPYBBgAACIABAAAAAAAAAABmA38AADiIAQAAAAAAAAAAYoIPAAA/DAMAAAAAAAAAAGKA/wAAeAQGAAAAAAAgAABgwPADAGAEDAAAAAAAIwBgYMCA//PPBzgAAAAAQAYAOHBgAPD/w5/hAAAAAMAEAB4wcAAAAAD7gAEAAADAAAADODAAAAAA5wcDAAAAgAMABx0cAAAAAIY/BwAAAAB/gO8fDgAAAAAscQwAAAAAfsD3DwcAAAAAOOMAAAAAAADA+IMBAAAAADDCAwAAAAAAYN7AAAAAAABgBgMAAAAAAADHYAAAAAAAwAw2AAAAAAAww3AAAAAAAMANbgAAAAAAmMExAAAAAACADewAAAAA/syAEQAAAAAAgA/YAAAAAI9kgBkAAAAAAAAXmAEAAACHMwAbAAAAAAAAPrgDAAAAjjEAEwAAAAAAAHz4AwAAAJgYABIAAAAAAAD88AcAAADgHwA2AAAAAAAA+MEMAAAAwAcANgAAAAAAAPBDDAAAAAACAGwAAAAAAAAwwggAAAAAAADMAAAAAAAAYIAfAAAAAAAAiAEAAAAAAOAcFAAAAAAAAIwBAAAAAADAewAAAAAAAAC+AwAAAAAAgPcAAAAAAAAAPA8AAAAAAADGAQAAAAAAAEAdAAAAAAAA/gMAAAAAAADgPwAAAAAAAPwAAAAAAAAA4D8AAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
12
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwH8AAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAA8H8DAAAAAAAAAAAAAAAAAH4ABwAAAAAAAAAAAAAAAIAPAAwAAAAAAAAAAAAAAATgAQAYAAAAAAAAAAAAAAAAPAAAMAAAAAAAAAAAAAAAAA8AIHgAAAAAAAAAAAAAAMADACDYAAAAAAAAAAAAAAD+AAAwkAEAAAAAAAAAAACADwAAOBADAAAAAAAAAAAAwAMAADgAAwAAAAAAAPwfAPABAABwAAYAAAAAAID/////AAAA/AMMAAAAAADAB4A/AAAAAAEPAAAAAAAA4AEAAAAADMABOAwAAAAAAH8AAAAAAADgAHAMAAAAAOAfAAAAAABgMABADAAAAIC7DwAAAAAAQBgAAAAAAADgzQ8AAAAAAMAcAAAAAAAA8AAOAAAAAACADwAAAAAAAHgADgAAAAAAgAcAAAAAAAA4AA4AAAAAAAADAAAAAAAACAAOAAAAAACAAQAAAAAAAAAADgAIAAAAgAEAAAAAAAAAAB4ADAAACIABAAAAAAAAAAAeAAwAAAiAAQAAAAAAAAAAvgAMAAAIgAEAAAAAAAAAAPYBBgAACIABAAAAAAAAAABmA38AADiIAQAAAAAAAAAAYoIPAAA/DAMAAAAAAAAAAGKA/wAAeAQGAAAAAAAgAABgwPADAGAEDAAAAAAAIwBgYMCA//PPBzgAAAAAQAYAOHBgAPD/w5/hAAAAAMAEAB4wcAAAAAD7gAEAAADAAAADODAAAAAA5wcDAAAAgAMABx0cAAAAAIY/BwAAAAB/gO8fDgAAAAAscQwAAAAAfsD3DwcAAAAAOOMAAAAAAADA+IMBAAAAADDCAwAAAAAAYN7AAAAAAABgBgMAAAAAAADHYAAAAAAAwAw2AAAAAAAww3AAAAAAAMAMbgAAAAAAmMExAAAAAACADewAAAAA/syAEQAAAAAAgA/YAAAAAI9kgBkAAAAAAAAXmAEAAACHMwAbAAAAAAAAPrgDAAAAjjEAEwAAAAAAAHz4AwAAAJgYABIAAAAAAAD88AcAAADgHwA2AAAAAAAA+MEMAAAAwAcANgAAAAAAAPBDDAAAAAACAGwAAAAAAAAwwggAAAAAAADMAAAAAAAAYIAfAAAAAAAAiAEAAAAAAOAcFAAAAAAAAIwBAAAAAADAewAAAAAAAAC+AwAAAAAAgPcAAAAAAAAAPA8AAAAAAADGAQAAAAAAAEAdAAAAAAAA/gMAAAAAAADgPwAAAAAAAPwAAAAAAAAA4D8AAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
13
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+PgAAAAAAAAAAAAAAAAAA4DwAAAAAAAAAAAAAAAAAAMAtAAAAAAAAAAAAAAAAABj43wAAAAAAAAAAAAAAAAAMEMABAAAAAAAAAAAAAAAAwAGAAwAAAAAAAAAAAAAAwGAAAAcAAAAAAAAAAAAAAHA4AAAMAAAAAAAAAAAAAMAgDgAMDwAAAAAAAAAAAADwBwYADB8AAAAAAAAAAAAA8IcAAA42AAAAAAAAAAAAAAB8AAAOZAAAAAAAAAAAAAAADwAADmAAAAAAAAAA/AcAgAMAAA7AAAAAAAAAgP/+APABAAB/gAEAAAAAAPAB4P8/AACA4YEBAAAAAAA4AAjgAQAAAAAHAQAAAAAAHgAAAAAAAAAAjgEAAAAAgAsAAAAAAAAAAIwBAAAAAOAEAAAAAAAAGACIAQAAAAAABAAAAAAAQAwAAAAAAAAACAQAAAAAAMAMAAAAAAAAAA4GAAQAAACABgAAAAAAAAADBAAEAAAAgAMAAAAAAACAAQQABAAAAIABAAAAAAAAAAAAAAQAAAAAAQAAAAAAAAAAAAAGAAAAAAMAAAAAAACAAAAABgAAAAADAAAAAAAAEAAAAAMAAAAAAwAAAAAAABCAF4ADAAAAAAMAAAAAAAAA8A+AHwAAAIADAAAAAAAACBAM4B8AAADAAwAAAAAAAAwGDvA5AAAA4AIAAAAAAAAGGgc4cAAAOGAGAAAAAAAABpwDHMAHAPAADAAAAAAAAAf9AA4A/wzcARgAAAAAAICDv4AHAPD/HwcwAAAAAADDgz/gAQAADAyUYAAAAACg4cEHeAAAAACE8cMBAAAA8IDBDw4AAAAAhMCPAwAAAODP4AsBAAAAAMQABwcAAAAARnPDAQAAAABEABwOAAAAAIB/wwAAAAAAZABwDAAAAADAvAEAAAAAAGYA4AgAAAAA4I0ZAAAAAABmAIBjAAAAAHDQDAAAAAAAZgAAxwMAAAD4/wYAAAAAADYAANgPAAAA/HcDAAAAAAA2AABwHAAAAAC8AwAAAAAAHgAAwPEAAADAnAEAAAAAAB4AAIDvAwAA8McAAAAAAAAPAAAAjw8AALjjAAAAAAAADwAAAAgAAAAcfwAAAAAAgA8AAAD4AQAALD8AAAAAAIALAAAA8AEAAP4/AAAAAACADwAAAAAAAAB4AAAAAAAAwAwAAAAAAAAAAAAAAAAAAMAMAAAAAAAAAAAAAAAAAADADAAAAAAAAAAAAAAAAAAAgA8AAAAAAAAAAAAAAAAAAAA7AAAAAAAAAAAAAAAAAAAAcwAAAAAAAAAAAAAAAAAAAOMAAAAAAAAAAAAAAAAAAAD/AQAAAAAAAAAAAAAAAAAA/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
14
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAfAAAAAAAAAAAAAAAAAADAHAAAAAAAAAAAAAAAAAAA4A8AAAAAAAAAAAAAAAAAIPhvAAAAAAAAAAAAAAAAAPAcwAAAAAAAAAAAAAAAAACAAIABAAAAAAAAAAAAAAAAAgAAAwAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAMAIYPAAAAAAAAAAAAAABwBgCHCwAAAAAAAAAAAAAAAAMAAxgAAAAAAAAAAAAAQIADAAcTAAAAAAAAAAAAAAD+AAAHIAAAAAAAAADwAQAAHgAAD2AAAAAAAAAA/x8AgAcAgHvAAAAAAAAAwAf4B8ABAIDhgQAAAAAAAHAAAOdvAAQAgIMAAAAAAIAfAAAAAAAMAADGAAAAAADwAwAAAAAAGAAAxAAAAAAAeAEAAAAAABgQAMQAAAAAAOAFAAAAAAAwGAAAAAAAACwgDAAAAAAAIAwAAAAAAAABAAQAAAAAAEAMAAAAAAAAAAAEAAAAAAAABgAAAAAAAAAADAAAAAAAAAYAAAAAAAAAAAwABAAAAIADAAAAAAAAQAAMAAAAAACAAQAAAAAAAAAADAAAAAAAgAEAAAAAAAAwAAwAAQAAAIABAAAAAAAAGOAPgAEAAACAAQAAAAAAYAzwDYABAAAAgAEAAAAAACAE8AbAHwAAAMAAAAAAAAAwBJADwAcAAADAAAAAAAAAMwH+ATAfAAAAQAAAAAAAABMBfgAA+AAAAAAAAAAAAACbAR8AAOAHAACIAAAAAAAA24EDwAEA/wNgjAAAAAAAAOuAAf4AAPD//4ABAAAAAIDvgMAfAAAA4PkDAQAAAADA98DgAAAAAGCYFwMAAAAA4HpgeAAAAABgDDwDAAAAAMA/YE4AAAAAcAd4BgAAAACADzBHAAAAAHAD+AYAAAAAAACYZwAAAAA4A+AMAAAAAAAAzmcAAAAAuAEAHAAAAAAAMMM7AAAAAIwAABgAAAAAAPjjPgAAAADMAIAxAAAAAAD8sQ4AAAAAbAAAMQAAAAAAPvwHAAAAADYAACYAAAAAAPf/AAAAAAAbAAAcAAAAAID/NwAAAAAACwAAOAAAAACADwAAAAAAgA0AAHAAAAAAAAAAAAAAAMAGAADgBgAAAAAAAAAAAABgBgAAwBwAAAAAAAAAAAAAcAMAAAA4AAAAAAAAAAAAADADAAAA8AAAAAAAAAAAAAAcAQAAAOMHAAAAAAAAAAAA+AEAAAA+PgAAAAAAAAAAALABAAAA+BAAAAAAAAAAAAAgAwAAAOAEAAAAAAAAAAAAYA8AAADABwAAAAAAAAAAAOAPAAAAAAAAAAAAAAAAAADgHQAAAAAAAAAAAAAAAAAA4D8AAAAAAAAAAAAAAAAAAOA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
15
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAMAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAC8HwAAAAAAAAAAAAAAAAAAxDcAAAAAAAAAAAAAAAAAAAxwAAAAAAAAAAAAAAAAAOAPwAAAAAAAAAAAAAAAAADfA4ABAAAAAAAAAAAAAAAA/wHBAwAAAAAAAAAAAAAAAP4A4QcAAAAAAAAAAAAAAAB8gMEGAAAAAAAAAAAAAAAAHoCBDQAAAAAAAAAAAAAAFA+AARgAAAAAAAAAAAAAAJwPgAMQAAAAAAAAAAAAAAD4B4APcAAAAAAAAAD/HwAA/AGAfWAAAAAAAADAv/8DAB8AwOBAAAAAAAAA4ADgf8APAOCAYQAAAAAAgD8AAPD/AQBgAGMAAAAAAPgfAAAASAAIMABgAAAAAAC/AQAAAAAAGDAAAAAAAADA9wkAAAAAABgYAAAAAAAAeDwIAAAAAAAwDAAAAAAAAA4GDAAAAAAAYAwAAAAAAAAAAAwAAAAAAGAGAAAAAAAAAAAMAAQAAABgBgAAAAAAAwAADAAGAAAAQAIAAAAAAAEAAAwAAgAAAMADAAAAAIABAAA8AAIAAADAAwAAAACAAAAALAADAAAAwAEAAAAAAAAAAG4AAwAAAMAAAAAAAAAAAMAHgAEAAADAAAAAAAAAAAD8A4A/AAAAwAAAAAAAAAAA/gHAPwAAAMAAAAAAAAAAgGAA8A8AAAJgAAAAAAAAAMAAAPgfAAAHcAAAAAAAAABgAIA/fAAABzgAAAAAACAAYOD/D/AHAI4fAAAAAAAgADD8/wCA/8fsCwAAAAAAYACIDwAAAPj//wgAAAAAAGAIjAEAAAAA/zkYAAAAAABgBocABgAAAOMwGAAAAAAAPOIxAAYAAABhYBgAAAAAACDsGAAGAACAM+AZAAAAAAAAfA7ABgAAwBjAGwAAAAAAADMHgAYAAOAcwBgAAAAAAIDrA0AGAABgDoAZAAAAAACA/QF4BgAAYAaAMwAAAAAAwF8AfAYAADADACMAAAAAAMAPAEwDAAAAAQAjAAAAAAAAAADeAwAADgAAZgAAAAAAAAAA4gAAAD8AAGQAAAAAAAAAAAIAAMAfAAAMAAAAAAAAAAACAADwDgAAaAAAAAAAAAAAAAAAMAYAABgAAAAAAAAAAAAAAD4DAAAQAAAAAAAAAAAAAAD/AQAAsAAAAAAAAAAAAACA9QAAALABAAAAAAAAAAAAgD0AAABgAwAAAAAAAAAAAMAPAAAAYAMAAAAAAAAAAADAAQAAAGAGAAAAAAAAAAAAAAAAAADgDAAAAAAAAAAAAAAAAAAA4A8AAAAAAAAAAAAAAAAAAIA7AAAAAAAAAAAAAAAAAAAA+wAAAAAAAAAAAAAAAAAAAN8BAAAAAAAAAAAAAAAAAAD+AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
16
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAADAAQAAAAAAAAAAAAAAAAAAfAcAAAAAAAAAAAAAAAAAAPwPAAAAAAAAAAAAAAAAAAAeGQAAAAAAAAAAAAAAAADgADAAAAAAAAAAAAAAAAAA8ABgAAAAAAAAAAAAAAAAAPAAwAAAAAAAAAAAAAAAAADwgOABAAAAAAAAAAAAAAAAfcDwAwAAAAAAAAAAAAAAAD/AYAcAAAAAAAAAAAAAAAAewMAGAAAAAAAAAAAAAADAAcAACAAAAAAAAAAAAAAA+AXAARgAAAAAAAAAAAAAAH4AwA8wAAAAAAAAAPgfAAAeAMA+IAAAAAAAAAA/OACABwBg4DAAAAAAAACAAwD/5wAAAMAxAAAAAAAAAAAY/G8AAACAMQAAAAAAAAwAEAAAAAAAABAAAAAAAMAPAAAAAAAAAAAAAAAAAADgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAQAAAAAAAAAPggAAAAAACAGAAAAAIAHAAwIAAAAAAAAAgAAAADAAYADGAAAAAAAQAMAAAAA4ADwARgADAAAAAADAAAAAGAAeAAYAAwAAACAAQAAAAAwCAgAEAAMAAAAwAAAAAAAEAwAADAABgAAgAAAAAAAABAAAAA4AAYAAAAAAAAAAADQAgAAHAAPAAAAAAAAAAAAUAIAAA8APwAAADAAAAAAADACAP4AwD8AgAEwAAAAAAAQAAACAPB4AIABHAAAAAAAGAEAAAA+4AeAAwwAAAAAABgGAAPwH4D/AGMCAAAAAAB4AwAD/wEA8D9/AwAAAAAAvAMA4zEAAACABwMAAAAAAP4BAHMkAAAAgIcBAAAAAAB+AAAZbAAAAICGAAAAAAAAAAAAHWwAAADAxwAAAAAAAAAAgA1sAAAAwMcAAAAAAAAAAIAOzAAAAOBGAAAAAAAAAAAgBswAAABwZgAAAAAAAAAAOAfIAAAAGG8AAAAAAAAAAB8DiAEA+IdnAAAAAAAAAACPA5gBgPzDYwAAAAAAAABAhgGwAcAP/DMAAAAAAAAAQP8AsAHwxg8xAAAAAAAAAGB/ALgB+P8AGAAAAAAAAABgBwC4AVwbABkAAAAAAAAA8AMA+AF8AAABAAAAAAAAAPABAJABHACAAQAAAAAAAABAAACwAAAAgAUAAAAAAAAAAAAA8AAAAIAEAAAAAAAAAAAAAOAAAADABgAAAAAAAAAAAADAAAAAwAYAAAAAAAAAAAAAAAAAAGAGAAAAAAAAAAAAAAAAAAAwBgAAAAAAAAAAAAAAAAAAMAMAAAAAAAAAAAAAAAAAAOAHAAAAAAAAAAAAAAAAAADADQAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIBzAAAAAAAAAAAAAAAAAACA/gAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
17
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAPwBAAAAAAAAAAAAAAAAAAD8AwAAAAAAAAAAAAAAAAAA+A8AAAAAAAAAAAAAAAAAIIAcAAAAAAAAAAAAAAAAAKgBOAAAAAAAAAAAAAAAAACsAHAAAAAAAAAAAAAAAAAApgBgAAAAAAAAAAAAAAAAAP7A8AAAAAAAAAAAAAAAAMD8wPABAAAAAAAAAAAAAABAGGAgAwAAAAAAAAAAAAAAAABgYAMAAAAAAAAAAAAAAAAC4AAGAAAAAAAAAAAAAAAAAuAADAAAAAAAAAAAAAAATwPgBxgAAAAAAAAA4A8AwH8DYB4YAAAAAAAAAPx/AMD/AQBwCAAAAAAAAAAP4P//cQAA4BgAAAAAAACAAwD/PwAAEMAYAAAAAAAA4AAAwAAAAhiACAAAAAAAAHAAAAAAAAYIAAAAAAAAAAAeAAAAAAAECAAAAAAAAADgBwAAAAAADAwAAAAAAAD8+QcAAAAAAAgEAAAAAADg/8EHAAAAAAAIBAAAAAAAfACAGAAAAAAAAAYAAAAAgH8AcBgAAAAAAAACAAAAAMABAD8YABAAAAAAAwAAAAAAAAADEAAQAAAAAAEAAAAAAAAAATAAGAAAAIABAAAAAAAAAAEwABgAAADAAAAAAAAACHAAMAAYAAAA4AAAAAAAAA8/AGAAGAAAAGAAAAAAAMAAAwDgAAwAQAAwAAAAAABgAAAA8AB8AEAAMAAAAAAAMAAAADAAfABAADgAAAAAABgAAAAcAP4AQAAcAAAAAAAMDgDwA8DcBwAABgAAAAAADAcA+AHwD3/gCAMAAAAAAAwDABgAvwP4f44BAAAAAADGAQAA4OMBAOABAAAAAAAAYwAACGZ+AADg4AAAAAAAADkAAAifDwAAYPAAAAAAAAAIAAAIsAMAAOD4AAAAAAAAAAAAiDAGAADw3AAAAAAAAAAAAMhgBgAAcM4AAAAAAAAAAADIwAwAAHjPAAAAAAAAAAAAzIAJAACYzwAAAAAAAAAAAEyAGQAAzuwAAAAAAAAAAABMABMAeMbMAAAAAAAAAAAATAAjAB7nZwAAAAAAAAAAAGQAZwAH42MAAAAAAAAAAIBnAGYAjzk+AAAAAAAAAACAYwBsAJj9HwAAAAAAAAAAgDAAbACACwAAAAAAAAAAAIAdAG4AkAEAAAAAAAAAAAAgDgBOANgBAAAAAAAAAAAAIAcAXgDsAAAAAAAAAAAAALABAEwAYgAAAAAAAAAAAAAwAABMADMAAAAAAAAAAAAAAAAAQIAxAAAAAAAAAAAAAAAAAECAGQAAAAAAAAAAAAAAAAAAgA0AAAAAAAAAAAAAAAAAAIANAAAAAAAAAAAAAAAAAAAAGwAAAAAAAAAAAAAAAAAAACMAAAAAAAAAAAAAAAAAAIBjAAAAAAAAAAAAAAAAAAAAwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
18
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAA+N8BAAAAAAAAAAAAAAAAAMwBBwAAAAAAAAAAAAAAAABmAA4AAAAAAAAAAAAAAAAAPgAYAAAAAAAAAAAAAAAAAB4QPgAAAAAAAAAAAAAAAMAOGG4AAAAAAAAAAAAAAABgBxjIAAAAAAAAAAAAAAAA4AMYCAAAAAAAAAAAAAAAAPABGAADAAAAAAAAAAAAAADwATAABgAAAAAAAAAAAAAA8AHwAQQAAAAAAAAAAAAAAOAB8A8EAAAAAAAAAAAAAAD2Axg4BAAAAAAAAAAADAAA/wAIcAQAAAAAAAAAwP8AwH8ADOAEAAAAAAAAAPD/f/9/AAzAAQAAAAAAAAA8AP7/fwAMAAAAAAAAAAAADwAAwHcABAAAAAAAAAAAgAMAAAAwAAQAAAAAAAAAAMABAAAAAAAEAAAAAAAAAADgAAAAAAAABgAAAAAAAAAAcAAAAAAAAAYAAAAAAAAAADgAIAAAAAAGAAAAAAAAAAA+ACAAAAAAAgAAAAAAgAPANwBgAAAAGAMAAAAAAP///zEAYAAAADADAAAAAMAP/P83AGAAAACwAQAAAADwAADgIwFAAAAAoAEAAAAAGAAAAGABQAAAAOAAAAAAAAAAAABgBsAAAADgAAAAAAAAAAAAwAzAAIAA4AAAAAAAAAAAAMAZQADAAPAAAAAAAAAEAAAAB2AAwAD4AAAAAADABQAAAB7wAMAAeAAAAABAYCAAAAAe8AHAAHgAAAAAQBwwAAAABvgfwPg/AAAAAEAWAAAAAAMe/v9/fwAAAABABgAAAIADB+P/l2MAAAAAwAYAAADwgQ8DgIFhAAAAAMAGAAAAfOAMA4DBwAAAAACAAQAAAAY44A+AwsMBAAAAAAEAAAAGHvAfgGPHAQAAAAAAAAAADAfwe4BzPgMAAAAAAAAAABgDzPuAM3gGAAAAAAAAAAAwAc7PgRvgBAAAAAAAAAAAcALPnIMIwAQAAAAAAAAAAGAG/zjPDOAAAAAAAAAAAADADh/x/QxwAAAAAAAAAAAAgB0ewycGvAMAAAAAAAAAAIA7PAcPB84BAAAAAAAAAAAAc/AO/ON3AAAAAAAAAAAAAGfAc/D8PwAAAAAAAAAAAABugMcAegwAAAAAAAAAAAAAbADPAD8HAAAAAAAAAAAAAG4AnoHpAwAAAAAAAAAAAABmAHzH/wEAAAAAAAAAAAAAcADw5h8AAAAAAAAAAAAAAHYA4I0AAAAAAAAAAAAAAABsAGAMAAAAAAAAAAAAAAAAfADAHwAAAAAAAAAAAAAAAHgAgB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
19
|
+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAA+N8BAAAAAAAAAAAAAAAAAMwBBwAAAAAAAAAAAAAAAABmAA4AAAAAAAAAAAAAAAAAPgAYAAAAAAAAAAAAAAAAAB4QPgAAAAAAAAAAAAAAAMAOGG4AAAAAAAAAAAAAAABgBxhIAAAAAAAAAAAAAAAA4AMYCAAAAAAAAAAAAAAAAPABGAADAAAAAAAAAAAAAADwATAABgAAAAAAAAAAAAAA8AHwAQQAAAAAAAAAAAAAAOAB8A8EAAAAAAAAAAAAAAD2Axg4BAAAAAAAAAAADAAA/wAIcAQAAAAAAAAAwP8AwH8ADOAEAAAAAAAAAPD/f/9/AAzAAwAAAAAAAAA8AP7/fwAMAAAAAAAAAAAADwAAwHcABAAAAAAAAAAAgAMAAAAwAAQAAAAAAAAAAMABAAAAAAAEAAAAAAAAAADgAAAAAAAABgAAAAAAAAAAcAAAAAAAAAYAAAAAAAAAADgAMAAAAAAGAAAAAAAAAAA+ACAAAAAAAgAAAAAAgAPANwBgAAAAGAMAAAAAAP///zEAYAAAADADAAAAAMAP/P83AGAAAACwAQAAAADwAADgIwBAAAAAoAEAAAAAGAAAAGAAQAAAAOAAAAAAAAAAAABgBsAAAADgAAAAAAAAAAAAwAzAAIAA4AAAAAAAAAAAAMAZQADAAPAAAAAAAAAEAAAAB2AAwAD4AAAAAADABwAAAB7wAMAAeAAAAABAYAAAAAAe8AHAAHgAAAAAQBwQAAAABvgfwPg/AAAAAEAUAAAAAAMe/v9/fwAAAABABgAAAIADB+P/l2EAAAAAwAYAAADwgQ8DgIFhAAAAAMAGAAAAfOAMA4DBwAAAAACAAQAAAAY44A+AwsMBAAAAAAEAAAAGHvAfgGPHAQAAAAAAAAAADAf0e4BzPgMAAAAAAAAAABgDzPuAM3gGAAAAAAAAAAAwAc7PgRvgBAAAAAAAAAAAcALPnIMIwAQAAAAAAAAAAGAGzzjPDOAAAAAAAAAAAADADp/x/QxwAAAAAAAAAAAAgB2ewycGnAMAAAAAAAAAAIA7PAcOB84BAAAAAAAAAAAAc/Ae/ON3AAAAAAAAAAAAAGfAc/D8PwAAAAAAAAAAAABugMcAegwAAAAAAAAAAAAAbADPAD8HAAAAAAAAAAAAAG4AnoHpAwAAAAAAAAAAAABmAHzH/wEAAAAAAAAAAAAAcADw5h8AAAAAAAAAAAAAAHYA4I0AAAAAAAAAAAAAAABsAGAMAAAAAAAAAAAAAAAAfADAHwAAAAAAAAAAAAAAAHgAgB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
|
|
20
|
+
];
|
|
@@ -8,6 +8,7 @@ export const receiverStyleRegistry = [
|
|
|
8
8
|
{ id: 'cyclone', maxRows: 14, minRows: 7 },
|
|
9
9
|
{ id: 'nebula', maxRows: 14, minRows: 7 },
|
|
10
10
|
{ id: 'lava-lamp', maxRows: 14, minRows: 7 },
|
|
11
|
+
{ id: 'gallop-fine', maxRows: 18, minRows: 7 },
|
|
11
12
|
{ id: 'motion-contour', maxRows: 14, minRows: 8 },
|
|
12
13
|
{ id: 'ribbon', maxRows: 12, minRows: 7 },
|
|
13
14
|
{ id: 'braille-wave', maxRows: 12, minRows: 7 },
|
|
@@ -30,7 +31,7 @@ export const receiverStyleRegistry = [
|
|
|
30
31
|
{ id: 'rotozoomer', maxRows: 14, minRows: 7 },
|
|
31
32
|
{ id: 'mesh', maxRows: 14, minRows: 7 },
|
|
32
33
|
{ id: 'hologram', maxRows: 12, minRows: 7 },
|
|
33
|
-
{ id: '
|
|
34
|
+
{ id: 'equalizer', maxRows: 12, minRows: 7 },
|
|
34
35
|
{ id: 'tunnel', maxRows: 14, minRows: 7 },
|
|
35
36
|
{ id: 'kaleidoscope', maxRows: 14, minRows: 7 },
|
|
36
37
|
{ id: 'phosphene', maxRows: 14, minRows: 7 },
|
|
@@ -60,12 +61,21 @@ export const receiverStyleRegistry = [
|
|
|
60
61
|
{ id: 'skyline', maxRows: 14, minRows: 7 },
|
|
61
62
|
{ id: 'golden-gate', maxRows: 14, minRows: 7 },
|
|
62
63
|
{ id: 'manhattan', maxRows: 14, minRows: 7 },
|
|
63
|
-
{ id: 'alpine', maxRows: 14, minRows: 7 }
|
|
64
|
+
{ id: 'alpine', maxRows: 14, minRows: 7 },
|
|
65
|
+
{ id: 'crossfade', maxRows: 14, minRows: 7 },
|
|
64
66
|
];
|
|
65
67
|
export const receiverStyleNames = receiverStyleRegistry.map(style => style.id);
|
|
66
|
-
export const defaultReceiverStyle = '
|
|
68
|
+
export const defaultReceiverStyle = 'gallop-fine';
|
|
67
69
|
export const receiverStyleMetadata = Object.fromEntries(receiverStyleRegistry.map(style => [style.id, style]));
|
|
68
70
|
const retiredReceiverStyleNames = [
|
|
71
|
+
'duplex-wave', 'color-drift', 'undertow', 'cube-tide', 'parallax-slabs', 'voxel-swell',
|
|
72
|
+
'dot-current', 'flip-matrix', 'raster-harp',
|
|
73
|
+
'spin-lattice', 'packet-storm', 'spark-chamber',
|
|
74
|
+
'magnetic-bloom', 'liquid-chrome', 'vector-braid', 'halftone-orbit',
|
|
75
|
+
'sonic-fan', 'raster-disc', 'diamond-current', 'velvet-vortex',
|
|
76
|
+
'din-stack', 'bass-shutters', 'velvet-dither', 'chrome-sweep', 'prism-steps', 'stereo-iris',
|
|
77
|
+
'phosphor-marquee', 'ascii-drive', 'prism-bank', 'gallop', 'gallop-ultrafine',
|
|
78
|
+
'gallop-solid', 'gallop-shaded', 'gallop-dither', 'gallop-hatch', 'gallop-scanline',
|
|
69
79
|
'scope', 'spectrum', 'oscilloscope', 'sdr', 'signal', 'retro', 'neon', 'waterfall',
|
|
70
80
|
'cassette', 'casette', 'stars', 'radio-waves', 'raindrops', 'vinyl', 'soundwave',
|
|
71
81
|
'spectrum-3d', 'tuning-dial', 'rf-constellation', 'rf-constelation', 'sphere', 'mobius',
|
|
@@ -86,14 +96,11 @@ const retiredReceiverStyleNames = [
|
|
|
86
96
|
'harmonic-harp', 'neon-transit', 'lantern-drift', 'murmuration', 'koi-shoal',
|
|
87
97
|
'calligraphy', 'aperture-bloom', 'kintsugi', 'sonic-loom', 'river-delta',
|
|
88
98
|
'peacock-plume', 'eclipse-corona', 'cloud-chamber', 'origami-tide', 'tv-static',
|
|
89
|
-
'sunspot', 'plasma', 'metaballs', 'moonlit-tide', 'motion-blob', 'clifford', 'paris',
|
|
99
|
+
'sunspot', 'plasma', 'metaballs', 'moonlit-tide', 'motion-blob', 'clifford', 'mirror', 'paris',
|
|
90
100
|
'kyoto', 'sahara'
|
|
91
101
|
];
|
|
92
102
|
const retiredReceiverStyles = new Set(retiredReceiverStyleNames);
|
|
93
103
|
export function migrateReceiverStyle(value) {
|
|
94
|
-
if (value === 'equalizer') {
|
|
95
|
-
return 'ultracode';
|
|
96
|
-
}
|
|
97
104
|
if (value === 'sumi-mountains' || value === 'moonlit-tide') {
|
|
98
105
|
return 'sumi-ocean';
|
|
99
106
|
}
|