first commit

This commit is contained in:
Jonathan Ferwerda 2026-05-01 17:16:19 -04:00
commit 83d295c8a8
932 changed files with 496934 additions and 0 deletions

392
Alarm.pl Executable file
View File

@ -0,0 +1,392 @@
#!/usr/bin/perl
use strict;
use warnings;
package Alarm;
use Mojolicious::Lite;
use List::Util qw(shuffle);
use Mojo::Util qw/html_unescape term_escape/;
use Time::Duration;
use Date::Parse;
use Time::Piece;
use Crypt::Simple;
use File::Slurp;
use Mojo::JSON qw(decode_json encode_json);
use Data::Dumper;
use Time::HiRes qw(gettimeofday time);
require "./gb.pl";
require "./subroutines.pl";
require "./Manager.pl";
require "./Websocket.pl";
my $config_file = read_file('./config.json');
my $config = decode_json $config_file;
our $logfile = &subs::home($config->{'logfile'});
`touch $logfile` if not -e $logfile;
our $log = Mojo::Log->new(path => $logfile);
my $device = &subs::device_setter();
my $last_moment = &subs::rightNow();
my $last_paper_moment = &subs::rightNow();
sub alarm_clock() {
my ($dber,$dot,$sql) = &subs::database_grabber();
return unless $dber;
my $timestamp = &subs::rightNow();
$last_moment = &subs::rightNow();
my $query = &subs::db_query('select * from appointments where (timestamp <= ? and seen is null) or ((type = ? or type = ? or type = ? or type=? or type = ?) and stop_timestamp is not null and stop_timestamp <= ? and stop_seen is null ) order by timestamp',
$timestamp, 'start','record','video','audio','screen',$timestamp);
my $alarm = $query->hashes;
my $duty_watch = &subs::db_query('select * from appointments where duties is not null and next_duty <= ? and next_duty is not null', $timestamp)->hashes;
foreach my $dw ( @{$duty_watch} ) {
my $duties = eval { return decode_json $dw->{'duties'} } || [];
my @seen_duties;
foreach my $duty ( @{$duties} ) {
my $jduty = encode_json $duty;
if ($duty->{'timestamp'} <= $timestamp) {
push @{$alarm}, {
app => $dw->{'app'},
type => $duty->{'duty'},
uuid => $dw->{'uuid'},
data => $jduty,
timestamp => $dw->{'timestamp'}
};
push @seen_duties, $duty->{'duuid'};
}
}
foreach my $sd ( @seen_duties ) {
@{$duties} = grep { $_->{'duuid'} && $_->{'duuid'} ne $sd } @{$duties};
}
my $next_duty = $duties->[0]->{'timestamp'};
@{$duties} = grep { $_->{'duuid'} } @{$duties};
@{$duties} = sort { $a->{'timestamp'} <=> $b->{'timestamp'} } @{$duties};
my $jduties = encode_json $duties;
if (scalar @{$duties} == 0) {
$jduties = undef;
}
&subs::db_update('appointments', { duties => $jduties, next_duty => $next_duty, server_time => &subs::rightNow() }, { app => $dw->{'app'}, uuid => $dw->{'uuid'} });
}
if (scalar @{$alarm} > 0) {
my $interval = 'second';
my $default_warranty = &subs::setting_grabber({ app => 'me', setting => 'warranty' }) || '-10d';
my $warranty = &subs::ago_calc($default_warranty, $timestamp);
my $t = &{$subs::time_subs->{$interval}}($timestamp);
my $t1 = ($timestamp - $t);
foreach my $a ( @{$alarm} ) {
&subs::db_query('update appointments set seen = ? where uuid=?', 'yes',$a->{'uuid'});
&subs::cache_delete({ app => $a->{'app'}, context => 'template' });
my $type = $a->{'type'};
if ($a->{'stop_timestamp'} && $a->{'stop_timestamp'} <= $timestamp && grep { $a->{'type'} eq $_ } qw/start video audio screen record/) {
if ($a->{'type'} eq 'start' || $a->{'type'} eq 'record') {
if ($a->{'type'} eq 'record') {
my $data = eval { return decode_json $a->{'data'} } || {};
my $recording_type = &subs::setting_grabber({ app => $a->{'app'}, setting => 'record' }) || 'system';
if ($data->{'recorder'} eq 'security') {
&Manager::record_video_stop({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
}
elsif ($data->{'recorder'} eq 'system') {
&Manager::record_audio_stop({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
}
else {
&Websocket::send('music', { console => 'jpStop(\'' . $a->{'app'} . '\',\'' . $data->{'recorder'} . '\',\'' . $a->{'uuid'} . '\');' });
}
}
else {
&subs::db_query('update appointments set seen = ?,type=?, stop_seen=? where uuid=?', 'yes','stop', 'yes',$a->{'uuid'});
}
&subs::intelligent_automation_toggle({ app => $a->{'app'}, 'state' => 'off', timestamp => $timestamp });
$type = 'stop';
my $sources = &subs::db_select('appointments', undef, { source_uuid => $a->{'uuid'} })->hashes;
foreach my $so ( @{$sources} ) {
push @{$sources}, @{&subs::db_select('appointments', undef, { source_uuid => $so->{'uuid'} })->hashes};
if ( $so->{'type'} eq 'start' && (!$so->{'stop_timestamp'} || $so->{'stop_timestamp'} <= $timestamp) ) {
my $dur = $so->{'timestamp'} - $timestamp;
&subs::db_update('appointments', { stop_seen => 'yes', type => 'stop', duration => $dur }, { source_uuid => $so->{'source_uuid'}, uuid => $so->{'uuid'} });
&budget_runner($so->{'app'});
&subs::intelligent_automation_toggle({ appt_uuid => $so->{'uuid'}, app => $so->{'app'}, 'state' => 'off', timestamp => $timestamp });
&Websocket::send('tab', { console => 'appointmentDetailGrabber(\'' . $so->{'app'} . '\',\'' . $so->{'uuid'} .'\');'});
}
}
}
else {
&subs::db_query('update appointments set seen = ?, stop_seen=? where uuid=?', 'yes', 'yes',$a->{'uuid'});
}
&Websocket::send('tab', { console => 'appointmentDetailGrabber("' . $a->{'app'} . '","' . $a->{'uuid'} .'");' });
}
elsif ($a->{'type'} eq 'start' || $a->{'type'} eq 'record') {
&subs::intelligent_automation_toggle({ app => $a->{'app'}, 'state' => 'on', timestamp => $a->{'timestamp'} });
my $sources = &subs::db_select('appointments', undef, { source_uuid => $a->{'uuid'} })->hashes;
foreach my $so ( @{$sources} ) {
push @{$sources}, @{&subs::db_select('appointments', undef, { source_uuid => $so->{'uuid'} })->hashes};
if ( $so->{'type'} eq 'start' && (!$so->{'stop_timestamp'} || $so->{'stop_timestamp'} <= $timestamp) ) {
&subs::db_update('appointments', { seen => 'yes' }, { source_uuid => $so->{'source_uuid'}, uuid => $so->{'uuid'} });
&budget_runner($so->{'app'});
&subs::intelligent_automation_toggle({ appt_uuid => $so->{'uuid'}, app => $so->{'app'}, 'state' => 'on', timestamp => $timestamp });
&Websocket::send('tab', { console => 'appointmentDetailGrabber(\'' . $so->{'app'} . '\',\'' . $so->{'uuid'} .'\');'});
}
}
if ($a->{'type'} eq 'record') {
my $recording_type = &subs::setting_grabber({ app => $a->{'app'}, setting => 'record' }) || 'system';
my $data = eval { return decode_json $a->{'data'} } || {};
if ($data->{'recorder'} eq 'security') {
&Manager::record_video({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
} elsif ($data->{'recorder'} eq 'system') {
&Manager::record_audio({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
}
elsif ($data->{'recorder'} eq 'screen') {
&Websocket::send('music', { console => 'jpScreen(\'' . $a->{'app'} . '\',\'' . $a->{'uuid'} . '\');' });
}
else {
&Websocket::send('music', { console => 'jpStart(\'' . $a->{'app'} . '\',\'' . $data->{'recorder'} . '\',\'' . $a->{'uuid'} . '\');' });
}
}
}
elsif ($a->{'type'} eq 'stop' || $a->{'type'} eq 'cancel') {
&subs::intelligent_automation_toggle({ app => $a->{'app'}, 'state' => 'off', timestamp => $timestamp });
}
elsif ($a->{'type'} eq 'image') {
my $data = decode_json $a->{'data'};
my $c = app->build_controller;
$c->stash('app' => $a->{'app'});
$c->session('timestamp' => $timestamp);
my ($file,$ocr) = &Manager::take_picture($c,{ app => $a->{'app'}, timestamp => $timestamp, camera => $data->{'camera'}, uuid => $a->{'uuid'} });
}
elsif ($a->{'type'} eq 'scan') {
my $scandata = decode_json $a->{'data'};
my $c = app->build_controller;
$c->stash('app' => $a->{'app'});
$c->stash('timestamp' => $a->{'timestamp'});
my $file = &Manager::scan($c, $scandata);
}
&subs::appt_header_printer({ app => $a->{'app'} });
my $settings = &subs::settings_grabber({ app => $a->{'app'} }) || {};
my $name = &subs::format_name($a->{'app'});
my $app = &subs::unformat_name($a->{'app'});
my $account = &subs::format_name($a->{'account'});
if ($settings->{'notification'} && $settings->{'notification'} eq 'on') {
&Manager::notification_sender({
app => $app,
role => 'all',
uuid => $a->{'uuid'},
type => $type,
settings => $settings,
sound => 'crystal.mp3',
title => $name,
},$dot);
}
if ($a->{'type'} =~ /command|kill|record/) {
my $command = $settings->{$a->{'type'}};
my $resulter = &subs::run_command($app,$command);
if ($a->{'type'} eq 'command') {
&subs::setting_setter({ app => $app, setting => 'toggle', value => 'on' });
}
elsif ($a->{'type'} eq 'kill') {
&subs::setting_setter({ app => $app, setting => 'toggle', value => 'off' });
}
}
}
}
my $ticket_query = &subs::db_query('select count(*) from tickets where status = ? and warranty < ?', 'active', $timestamp);
my $t_count = $ticket_query->text;
if ($t_count > 0) {
my $ticket_update_query = &subs::db_query('update tickets set status = ? where status = ? and warranty < ?', 'expired', 'active', $timestamp);
my $msg = { app => 'box_office', console => 'ticket_list()' };
my $server_time = &subs::rightNow();
&Websocket::send('server', $msg);
}
my $warranty_query = &subs::db_query('select * from appointments where warranty < ?',$timestamp);
my $haircut = $warranty_query->hashes;
foreach my $h ( @{$haircut} ) {
foreach my $t ( qw/appointments/ ) {
&Manager::delete_app($h->{'app'}, $h->{'uuid'},$h->{'server_time'},'alarm runner');
#&subs::db_delete($t, { app => $h->{'app'}, uuid => $h->{'uuid'} });
}
if (grep { $_ ne $h->{'app'} } qw/misc customs music __president me/) {
&subs::vacuum($h->{'app'});
}
}
my $backups = [];#&subs::db_query('select * from backups where warranty < ?', $timestamp)->hashes;
foreach my $b ( @{$backups} ) {
if (-e $b->{'destination'}) {
my $commander = 'shred -u ' . $b->{'destination'};
# `$commander`;
}
#&subs::db_delete('backups', { uuid => $b->{'uuid'} });
}
my $paper_q = &subs::db_query('select * from magazine where status=? and timestamp >= ? and timestamp <= ? and warranty >=?', 'publish',$last_paper_moment, $timestamp,$timestamp);
my $papers = $paper_q->hashes;
foreach my $paper ( @{$papers} ) {
my $c = app->build_controller;
$paper->{'art'} = $c->render_to_string(template => 'article', art => $paper);
&Manager::paperRoute($paper);
}
$last_paper_moment = &subs::rightNow();
&subs::db_query('delete from magazine where warranty < ?', $timestamp);
&subs::db_query('delete from continent where warranty < ?', $timestamp);
&subs::db_query('delete from websites where warranty < ?', $timestamp);
&subs::db_query('delete from cache where warranty < ?', $timestamp);
my $websocks = &subs::db_query('select * from websockets where warranty < ?', $timestamp);
foreach my $webs (@{$websocks->hashes}) {
my $art_query = &subs::db_query('delete from drawings where browser_tab_id = ?', $webs->{'browser_tab_id'});
my $del_query = &subs::db_query('delete from websockets where browser_tab_id = ?', $webs->{'browser_tab_id'});
}
}
sub budget_watcher() {
my ($db,$database,$sql) = &subs::database_grabber('memory');
unless (&subs::setting_grabber({ app => 'me', setting => 'budget_alarm', device => $device }) eq 'on') { return 0; }
my $w_time = &subs::rightNow() + &subs::time_abbrev_translator('1m',&subs::rightNow());
my $budgets = &subs::db_query('select distinct(app) as app,* from settings where setting = ? and device = ? and value is not null','budget', $device)->hashes;
my $settings;
foreach my $b ( @{$budgets} ) {
my $app = $b->{'app'};
my @buds = split /,/, $b->{'value'};
my $scope;
$settings->{$app} = &subs::settings_grabber({ app => $app }) unless $settings->{$app};
foreach my $circumstance ( keys %{$gb::budget_modes} ) {
my $cache_budget = &subs::cache_get({ app => $app, context => 'budget', subcontext => $circumstance });
if ($cache_budget->{'scope'}) {
$scope = $cache_budget->{'scope'};
}
foreach my $bud ( @buds ) {
my @bt = split '/', $bud;
$scope = $bt[-1];
if (1) {
my $budget = &Manager::budget_calculator({
app => $app,
circumstance => $circumstance,
scope => $scope,
budget => $bud,
settings => $settings->{$app}
});
if ($budget->{'is_scope'} && $circumstance eq $budget->{'circumstance'}) {
my $server_time = &subs::rightNow();
$budget->{'timestamp'} = &subs::rightNow();
&subs::cache_delete({ app => $app, context => 'template' });
&subs::cache_set({ app => $app, context => 'budget', subcontext => $circumstance }, $budget);
if ($cache_budget->{'status'} ne $budget->{'status'}) {
my $websockets = &subs::db_query('select * from websockets where app = ? and windows like ? and server_time > ? and windows is not null order by timestamp DESC',
'tab', '%app":"' . $app . '%', $server_time - 5000)->hashes;
if (scalar @{$websockets} > 0) {
my $msg = {
app => $app,
type => 'budget',
budget => {
colour => $budget->{'colour'},
circumstance => $budget->{'circumstance'},
}
};
&Websocket::send('tab', $msg);
&subs::appt_header_printer({ app => $app });
}
my $message = &subs::format_name($app) . ' is ' . $budget->{'status'} . ' for ' . $circumstance . ': ' . $budget->{'formatted_value'} . '/' . $budget->{'formatted_budgeted'};
if (&subs::setting_grabber({ app => $app, setting => 'notification', device => $device }) eq 'on') {
&Manager::notification_sender({
app => $app,
role => 'all',
title => &subs::format_name($app),
synth => $budget->{'synth'},
words => $app,
message => $message,
image => "/images/decipherable/chart.png",
type => 'budget'
},$database);
}
#&Manager::budget_autocalc({
# app => $app,
# circumstance => $circumstance,
#});
}
}
}
}
}
}
return 0;
}
sub housekeeping() {
my ($db,$database,$sql) = &subs::database_grabber();
my $server_time = &subs::rightNow();
my $settings = &subs::settings_grabber({ app => '__president', device => $device });
my @cache_folders = split /\n/, $settings->{'cache_folders'};
foreach my $cf (@cache_folders) {
if ($cf ne '/' && $cf ne &subs::home('~/') && $cf =~ /[a-z0-9A-Z]/) {
my $folder = &subs::home($cf);
my $doomed = `ls -a $cf`;
my @doomed = split /\n/, $doomed;
foreach my $doom ( @doomed ) {
my $rip = $folder . '/' . $doom;
unless ($doom eq '.' || $doom eq '..') {
# my $success = `shred -u $rip`;
}
}
}
}
my $expiration = &subs::ago_calc('-1h', $server_time);
my $websockets = &subs::db_query('delete from websockets where server_time < ? and room is not null', $expiration);
return 0;
}
sub task_checker() {
my $server_time = &subs::rightNow();
my $tasks = &subs::db_query('select app from settings where setting = ? and value is not null','tasks')->hashes;
foreach my $task ( @{$tasks} ) {
my $app = $task->{'app'};
my $taskskis = &subs::task_grabber($app);
my $websockets = &subs::db_query('select * from websockets where app = ? and windows like ? and server_time > ? and windows is not null order by timestamp DESC',
'tab', '%app":"' . $app . '%', $server_time - 5000)->hashes;
if (scalar @{$websockets} > 0) {
my $msg = {
app => $app,
type => 'html',
selector => '.re_tasks[app="' . $app . '"]',
content => $taskskis->{'html'}
};
&Websocket::send('server', $msg);
}
}
return 0;
}
1;

5
LICENSE.md Executable file
View File

@ -0,0 +1,5 @@
Copyright (c) 2013-2025 Jonathan Ferwerda
All rights reserved

12
Makefile.PL Executable file
View File

@ -0,0 +1,12 @@
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
VERSION => '0.01',
PREREQ_PM => {
'Mojolicious' => '9.33'
},
test => {TESTS => 't/*.t'}
);

15966
Manager.pl Executable file

File diff suppressed because it is too large Load Diff

625
Music.pl Executable file
View File

@ -0,0 +1,625 @@
#!/usr/bin/perl
use Mojolicious::Lite -signatures;
use Mojolicious::Static;
use Mojo::Log;
use Mojo::File;
use Mojo::JSON qw(decode_json encode_json);
use Encode qw(encode decode);
use List::Util qw(shuffle);
use Data::Dumper;
use Data::UUID;
use Mojo::Util qw/term_escape html_unescape url_unescape url_escape/;
use File::Find;
use File::Slurp;
plugin 'RenderFile';
use LWP::UserAgent;
use Mojolicious::Sessions;
use URI::Encode qw(uri_encode uri_decode);
use MIME::Base64;
use strict;
my $com = 'echo $HOME';
my $cwd = `$com`;
chomp $cwd;
require "./subroutines.pl";
my $device = &subs::device_setter();
my $config_file = read_file('./config.json');
my $config = decode_json $config_file;
my $environment = $config->{'environment'};
my @folders = @{$config->{'folders'}};
our $logfile = &subs::home($config->{'logfile'});
`touch $logfile` if not -e $logfile;
our $log = Mojo::Log->new(path => $logfile);
my (@results);
my $files = [];
my $thumb_files = [];
my $permissive = 0;
sub process_file() {
my $name = $File::Find::name;
if ($name =~ m/mp3$|m4a$|wav$|flac$|mp4$|mov$|webm$|weba$|wmv$/i) {
$name =~ s/^\.\///g;
push @{$files}, $name;
}
if ($permissive == 1) {
if ($name =~ m/mp3\.enc$|m4a\.enc$|wav\.enc$|flac\.enc$|mp4\.enc$|mov\.enc$|webm\.enc$|weba\.enc$|wmv\.enc$/i) {
$name =~ s/^\.\///g;
push @{$files}, $name;
}
}
}
sub process_thumbfile() {
my $name = $File::Find::name;
if ($name =~ m/jpg$|png$/i) {
$name =~ s/^\.\///g;
push @{$thumb_files}, $name;
}
}
get '/manager/music' => sub ($c) {
my $search = $c->param('search') || &subs::setting_grabber({ app => 'music', 'setting' => 'search' });
my $window_maker = $c->param('window_maker');
my $unlock = &subs::setting_grabber({ app => 'music', setting => 'combo_unlock' });
my $port = $c->req->url->base->port;
my $misses = eval { return decode_json $c->param('misses') } || {};
if (!$misses->{'video'}) {
$misses->{'video'} = &subs::random_string_creator(25,"Aa");
}
$files = undef;
my $settings = &subs::settings_grabber({ app => 'music' });
$settings->{'artist'} = eval { return decode_json $settings->{'artist'} } || [];
$settings->{'album'} = eval { return decode_json $settings->{'album'} } || [];
if ($settings->{'library'} ne 'local' && $c->param('remoted') ne 'yes') {
my $rm = &subs::db_query('select * from remote_machines where uuid=? and connection=?', $settings->{'library'}, 'active')->hashes->[0];
if ($rm->{'uuid'}) {
$c->param('remote_uuid' => $rm->{'uuid'});
$c->param('subprocess' => 'yes');
my $result = &Manager::remote_relay_request($c);
if ($result =~ /music/gi) {
$c->render(text => $result);
return;
}
}
else { &subs::setting_setter({ app => 'music', setting => 'library', value => 'local' }); $settings->{'library'} = 'local'; }
}
my $misc_settings = &Manager::misc_setting_list();
if (my $cache = &subs::cache_get({ app => 'music', context => 'content' })) {
if ($cache->{'contents'}) {
if ($c->param('window_maker')) {
my $website = &Manager::window_maker({ app => 'music', title => 'music', contents => $cache->{'contents'} }, &subs::rightNow());
$c->render(text => $website);
}
else {
$c->render(text => $cache->{'contents'});
}
return;
}
}
if ($unlock) {
if (secure_compare(&subs::note_decrypter($c->session('suds'), $unlock), &subs::note_decrypter($c->session('suds'), &subs::setting_grabber({ app => 'music', setting => 'combo_unlock' })) ) ) {
$permissive = 1;
}
}
my $crate = &music_search({ settings => $settings, c => $c, search => $search, now_playing => {}, port => $port, misc_settings => $misc_settings });
my $timestamp = &subs::rightNow();
my $jmao = &subs::setting_grabber({ app => 'music', setting => 'mao' });
my $player = &subs::cache_get({ app => 'music', context => 'player' });
my $resizes = eval { return decode_json $settings->{'resizes'} } || {};
my $contents;
if ($c->param('window_maker')) {
$contents = $c->render_to_string(
crate => $crate,
interface_colour => &subs::random_colour_grabber(),
template => 'apps/music/music',
window_maker => 'yes',
folders => $misc_settings,
device => &subs::device_setter(),
mao => eval { return decode_json $jmao } || {},
jmao => $jmao,
search => $search,
resizes => $resizes,
misses => $misses,
);
my $website = &Manager::window_maker({ app => 'music', title => 'music', contents => $contents }, $timestamp);
$c->render(text => $website);
}
else {
$contents = $c->render_to_string(
crate => $crate,
interface_colour => &subs::random_colour_grabber(),
template => 'apps/music/music',
layout => 'music',
window_maker => 'no',
folders => $misc_settings,
device => &subs::device_setter(),
mao => eval { return decode_json $jmao } || {},
jmao => $jmao,
search => $search,
resizes => $resizes,
misses => $misses
);
$c->render(text => $contents);
}
&subs::cache_set({ app => 'music', context => 'content' }, { contents => $contents });
};
get '/play' => sub($c) {
my $mao = eval { return decode_json &subs::setting_grabber({ app => 'music', setting => 'mao' }) } || {};
my $track = &subs::terminal_name(uri_decode $c->param('track'));
my $data;
&Manager::rock_and_roll($c);
if ($mao->{'srv'} eq 'on') {
Mojo::IOLoop->subprocess->run_p(sub {
if ($device eq 'computer') {
my $t = term_escape $track;
`vlc $track`;
}
elsif ($device eq 'mobile') {
`play $track`;
}
});
$c->render(text => 'play');
}
};
any '/music/receiver' => sub($c) {
my $file = $c->param('file');
my $remote_address = $c->tx->remote_address;
my $domain = $c->param('domain');
my $remote_uuid = $c->param('remote_uuid');
my $toggle = $c->param('toggle');
my $seek = $c->param('seek');
my $volume = $c->param('volume');
my $music_data = &subs::decrypter($c->session('suds'), decode_base64 $c->param('music_data'));
my $piped = &subs::home('~/.president/pipe');
my $timestamp = $c->param('timestamp');
my $latency = $c->param('latency');
my $queuing = $c->param('queuing');
my $server_time = &subs::rightNow();
my $pipe = $piped;
my @file = split /\./, $file;
my $ext = $file[-1];
if ($ext eq 'enc') {
$ext = $file[-2];
}
$pipe = $pipe . '.' . $ext;
my $ws_watcher = &subs::home('~/.president/ws_watcher');
my $pre_md = eval { return decode_json read_file($ws_watcher) } || {};
$log->info(Dumper $pre_md);
$log->info(Dumper $music_data);
write_file($ws_watcher, $music_data) unless $queuing == 1;
my $md = eval { return decode_json $music_data } || {};
if ($toggle eq 'off') {
`pkill play`;
`shred -u $piped*`;
`shred -u $ws_watcher`;
}
elsif ($toggle eq 'seek') {
`pkill play`;
$seek = $seek + ((&subs::rightNow() - $server_time) / 1000) + $latency;
threads->create(sub() {
`play $pipe trim $seek 60000000000`;
});
}
else {
my $rm = &subs::db_query('select * from remote_machines where (ip=? or fqdn=?) and connection=?', $remote_address,$domain,'active')->hashes->[0];
if ($rm->{'uuid'}) {
if ($md->{'file'} ne $pre_md->{'file'} || $queuing == 1) {
my $signatorial = &subs::signatorial_designer();
$rm = &remote_useragent_maker({ ip => $rm->{'ip'}, signatorial => $signatorial, rm => $rm });
my $url = $rm->{'manager'} . '/file_open?&file=' . uri_encode $file;
$rm->{'ua'} = $rm->{'ua'}->max_response_size(0);
my $res = $rm->{'ua'}->get($url);# => { Accept => '*/*' } => 'Content!');
my $data = $res->res->content->asset->slurp;
unless (-e $pipe) {
`touch $pipe`;
}
write_file($pipe, $data);
if ($queuing != 1) {
`pkill play`;
$seek = $seek + ((&subs::rightNow() - $server_time) / 1000) + $latency;
threads->create(sub() {
`play $pipe trim $seek 60000000000`;
});
}
}
else {
`pkill play`;
$seek = $seek + ((&subs::rightNow() - $server_time) / 1000) + $latency;
threads->create(sub() {
`play $pipe trim $seek 60000000000`;
});
}
}
}
$c->render(json => { timestamp => $timestamp, 'seek' => $seek, file => $file, toggle => $toggle, volume => $volume, type => 'transmitter' });
};
sub music_folder_grabber() {
my ($db,$database,$sql) = &subs::database_grabber();
my @folders = ();
my $settings = &Manager::misc_setting_list();
foreach my $s ( keys %{$settings->{$device}} ) {
if ($s =~ /_location$/gi) {
my $status = &subs::setting_grabber({ app => 'music_folder_toggle', setting => $s, device => $device });
push @folders, $settings->{$device}->{$s} if $status eq 'on';
}
}
return @folders;
}
sub music_search($data) {
my $search = $data->{'search'};
my $now_playing = $data->{'now_playing'};
my $settings = $data->{'settings'};
my $c = $data->{'c'};
my $misc_settings = $data->{'misc_settings'};
my $port = $data->{'port'};
my $misses = $data->{'misses'};
$files = [];
unless ($settings->{'uuid'}) {
$settings = &subs::settings_grabber({ app => 'music' });
$settings->{'artist'} = eval { return decode_json $settings->{'artist'} } || [];
$settings->{'album'} = eval { return decode_json $settings->{'album'} } || [];
}
$permissive = 1 if $settings->{'combo_unlock'};
my @folders;
if (scalar @{$settings->{'album'}} > 0) {
push @folders, map { $_->{'path'} } @{$settings->{'album'}};
}
elsif (scalar @{$settings->{'artist'}} > 0) {
push @folders, map { $_->{'path'} } @{$settings->{'artist'}};
}
else {
@folders = &music_folder_grabber();
}
foreach my $folder (@folders) {
$folder = &subs::home($folder);
if (-d $folder) {
find(\&process_file,$folder);
}
}
my @local_files = @{$files};
if ($search) {
@local_files = grep { lc $_ =~ /($search)/gi } @{$files};
}
my $crate = &song_maker({ c => $c, port => $port, files => \@local_files, settings => $settings, now_playing => $now_playing });
$permissive = 0;
return $crate;
}
sub song_maker($data) {
my $files = $data->{'files'};
my $settings = $data->{'settings'};
my $now_playing = $data->{'now_playing'};
my $c = $data->{'c'};
my $misc_settings = $data->{'misc_settings'};
my $port = $data->{'port'};
my $config = $data->{'config'};
my @local_files;
my $background_colour = &subs::setting_grabber({ app => 'misc', setting => 'manager_background_colour'});
my $computer_name = &subs::setting_grabber({ app => 'me', setting => 'computer_name' });
my $file_informations = {};
my ($cache_artists,$cache_albums);
if ($data->{'settings'}-{'all_albums'} eq 'yes') {
$cache_albums = &subs::cache_get({ app => 'music', context => 'albums' }) || {};
}
if ($data->{'settings'}->{'all_artists'} eq 'yes') {
$cache_artists = &subs::cache_get({ app => 'music', context => 'artists' }) || {};
}
if ($data->{'same_order'} != 1) {
if ($settings->{'shuffle'} eq 'on') {
@local_files = shuffle(@{$files});
}
else {
@local_files = sort @{$files};
}
}
else {
@local_files = @{$files};
}
my @lf;
my $track_number = 0;
my $max_files = &subs::setting_grabber({ app => 'misc', setting => 'max_files' } ) || 30;
my $tree = &subs::inventory_grabber();
my $artists = {};
my $albums = {};
my $songs = [];
my $pushed_now_playing = 0;
my $current_track;
splice @local_files, $max_files;
if ($now_playing->{'file'}) {
my @is = grep { $_ eq $now_playing->{'file'} } @local_files;
unshift @local_files, $now_playing->{'file'} unless grep { $_ eq $now_playing->{'file'} } @local_files;
}
for (my $n = 0; $n <= $max_files; $n++) {
my $f = $local_files[$n];
unless (-e $f) {
next;
}
$track_number = $track_number + 1;
my @t = split '/', $f;
my @temp_path = @t;
my $t = $t[-1];
my $track_number = 0;
$t =~ s/(\.mp3$|\.m4a$|\.wav$|\.flac$)//gi;
my $extension = $1;
my ($info,$type,@thumbs);
if ($extension) {
$type = 'audio';
}
else {
$type = 'video';
}
my $filename = $f;
my $full_title = $t;
$tree->{lc $t} = $t[-3];
$tree->{lc $t} .= "\n" . $t[-2] if $t[-2];
$tree->{lc $t} .="\n" . $tree->{lc $t};
pop @temp_path;
my $album_folder = join '/', @temp_path;
if ($type eq 'audio') {
$thumb_files = [];
find(\&process_thumbfile,$album_folder);
@thumbs = @{$thumb_files};
}
my $app;
if ($filename =~ /\.enc$/gi) {
$app = $t[-2];
}
my $formatted_name = &subs::format_name(join '.', $full_title);
pop @temp_path;
my $artist_folder = join '/', @temp_path;
$f = {
filename => $filename,
type => $type,
track => $t,
extension => $extension,
artist => $t[-3],
artist_folder => $artist_folder,
album => $t[-2],
app => &subs::unformat_name($t[-2]),
album_folder => $album_folder,
thumbs => \@thumbs,
info => $info,
song => $t[-1],
full_title => $full_title,
formatted_name => $formatted_name,
track_number => $track_number,
file_uuid => &subs::random_string_creator(21),
description => $tree->{lc $t},
computer_name => $computer_name,
colour => $background_colour
};
if ($filename && $filename !~ /\.enc$/gi) {
if (!$file_informations->{$artist_folder}) {
$file_informations->{$artist_folder} = &subs::cache_get({ app => 'music', context => 'file_information', subcontext => $artist_folder }) || {};
}
my $file_information = $file_informations->{$artist_folder};
if ($file_information->{$filename}) {
$f->{'info'} = $file_information->{$filename};
}
else {
$f = &subs::file_media_information($f, &subs::terminal_name($filename));
$file_information->{$filename} = $f->{'info'};
}
foreach my $i ( qw/artist album track genre title date composer publisher lyrics lyrics-eng/ ) {
if ($i =~ /lyrics/ && $f->{'info'}->{'tags'}->{$i}) {
$f->{'lyrics'} = $f->{'info'}->{'tags'}->{$i};
$f->{'lyrics'} =~ s/\\\n|\\\r/<br>/gi;
}
else {
$f->{$i} = $f->{'info'}->{'tags'}->{$i} if $f->{'info'}->{'tags'}->{$i};
}
}
}
if ($now_playing->{'file'} eq $filename) {
$current_track = $n;
$f->{'playing'} = 'yes';
}
else {
}
$artists->{$t[-3]}->{'full_title'} => $t[-3];
$artists->{$t[-3]}->{'path'} = $artist_folder;
push @{$artists->{$t[-3]}->{'tracks'}}, $f;
$albums->{$t[-2]}->{'full_title'} => $t[-3];
$albums->{$t[-2]}->{'path'} = $album_folder;
push @{$albums->{$t[-3]}->{'tracks'}}, $f;
push @{$songs}, $f;
if ($data->{'settings'}->{'all_artists'} eq 'yes') {
$cache_artists->{lc $f->{'artist'}} = { path => $artist_folder, artist => $f->{'artist'} };
}
if ($data->{'settings'}->{'all_albums'} eq 'yes') {
$cache_albums->{lc $f->{'album'}} = { path => $album_folder, album => $f->{'album'} };
}
}
foreach my $finfo ( keys %{$file_informations} ) {
&subs::cache_set({ app => 'music', context => 'file_information', subcontext => $finfo, warranty => '-6M' }, $file_informations->{$finfo});
}
if ($data->{'settings'}->{'all_artists'} eq 'yes') {
&subs::cache_set({ app => 'music', context => 'artists' }, $cache_artists);
$artists = $cache_artists;
}
if ($data->{'settings'}->{'all_albums'} eq 'yes') {
&subs::cache_set({ app => 'music', context => 'albums' }, $cache_albums);
$albums = $cache_albums;
}
my $crate = {
config => $config,
remote_uuid => $c->param('remote_uuid'),
current_track => $current_track,
artist => $settings->{'artist'},
album => $settings->{'album'},
artists => $artists,
albums => $albums,
songs => $songs,
settings => $settings,
};
return $crate;
}
post '/music/search' => sub ($c) {
my $title = 'music';
my $search = lc $c->param('search');
my $unlock = $c->param('unlock');
my $window_maker = $c->param('window_maker');
my $new_settings = eval { return decode_json $c->param('new_settings') } || {};
my $resizes = $c->param('resizes');
my $misses = eval { return decode_json $c->param('misses') } || {};
if (!$misses->{'video'}) {
$misses->{'video'} = &subs::random_string_creator(25,"Aa");
}
foreach my $ns ( keys %{$new_settings} ) {
&subs::setting_setter({ app => 'music', setting => $ns, value => $new_settings->{$ns} });
}
my $port = $c->req->url->base->port;
my $list = eval { return decode_json $c->param('list') } || [];
my $now_playing = eval { return decode_json $c->param('now_playing') } || {};
my $same_order = $c->param('same_order');
&subs::cache_delete({ app => 'music', context => 'content' });
my $artist = $c->param('artist');
my $album = $c->param('album');
my $misc_settings = &Manager::misc_setting_list();
if ($unlock) {
if (secure_compare(&subs::note_decrypter($c->session('suds'), $unlock), &subs::note_decrypter($c->session('suds'), &subs::setting_grabber({ app => 'gallery', setting => 'combo_unlock' })) ) ) {
$permissive = 1;
}
}
&subs::setting_setter({ app => 'music', setting => 'resizes', value => $resizes });
&subs::setting_setter({ app => 'music', setting => 'album', value => $album });
&subs::setting_setter({ app => 'music', setting => 'artist', value => $artist });
&subs::setting_setter({ app => 'music', setting => 'search', value => $search });
my $settings = &subs::settings_grabber({ app => 'music' });
if ($settings->{'library'} ne 'local' && $c->param('remoted') ne 'yes') {
$c->param('resizes' => undef);
my $rm = &subs::db_query('select * from remote_machines where uuid=? and connection=?', $settings->{'library'}, 'active')->hashes->[0];
if ($rm->{'uuid'}) {
$c->param('remote_uuid' => $rm->{'uuid'});
$c->param('subprocess' => 'yes');
my $result = &Manager::remote_relay_request($c);
if ($result =~ /music/gi) {
my $dom = Mojo::DOM->new($result);
$c->render(text => $result);
return;
}
}
else { &subs::setting_setter({ app => 'music', setting => 'library', value => 'local' }); $settings->{'library'} = 'local'; }
}
$settings->{'artist'} = eval { return decode_json $settings->{'artist'} } || [];
$settings->{'album'} = eval { return decode_json $settings->{'album'} } || [];
my $crate;
if (scalar @{$list} > 0) {
my $permissive = 1 if $settings->{'combo_unlock'};
$crate = &song_maker({ c => $c, config => $config, port => $port, files => $list, settings => $settings, now_playing => $now_playing, same_order => $same_order, misc_settings => $misc_settings });
}
else {
$crate = &music_search({ c => $c, search => $search, now_playing => $now_playing, settings => $settings, port => $port, misc_settings => $misc_settings });
}
my @interface_color= qw/yellow green blue orange black fuschia pink navy purple brown/;
my $random_number = rand(0..8);
my $timestamp = &subs::rightNow();
my $jmao = &subs::setting_grabber({ app => 'music', setting => 'mao' });
$artist = eval { return decode_json $artist } || [];
$album = eval { return decode_json $album } || [];
$resizes = eval { return decode_json $resizes } || {};
my $contents;
if ($c->param('window_maker')) {
$contents = $c->render_to_string(
crate => $crate,
interface_colour => $interface_color[$random_number],
template => 'apps/music/music',
window_maker => 'yes',
folders => $misc_settings,
device => &subs::device_setter(),
mao => eval { return decode_json $jmao } || {},
jmao => $jmao,
search => $search,
resizes => $resizes,
misses => $misses
);
my $website = &Manager::window_maker({ app => 'music', title => $title, contents => $contents }, $timestamp);
$c->render(json => { artist => $artist, album => $album, search => $search, html => $website });
}
else {
$contents = $c->render_to_string(
template => 'apps/music/files',
crate => $crate,
search => $search,
);
$c->render(text => $contents);
}
&subs::cache_set({ app => 'music', context => 'content' }, { contents => $contents });
};
post '/music/folder_toggle' => sub($c) {
my $timestamp = $c->param('timestamp');
my $location = $c->param('location');
my $status = $c->param('status');
&subs::setting_setter({ app => 'music_folder_toggle', setting => $location, value => $status, timestamp => $timestamp });
my $setting = &subs::setting_grabber({ app => 'music_folder_toggle', setting => $location, device => $device });
$c->render(text => $setting);
};
post '/music/audio_output_select' => sub ($c) {
my $output = $c->param('output');
my $state = $c->param('state');
my $mao = eval { return decode_json &subs::setting_grabber({ app => 'music', setting => 'mao' }) } || {};
$mao->{$output} = $state;
my $jmao = encode_json $mao;
&subs::setting_setter({ app => 'music', setting => 'mao', value => $jmao });
$c->render(json => $mao);
};
get '/music/configuration' => sub($c) {
my $returner = {};
my $settings = &subs::settings_grabber({ app => 'music' });
my $jmao = $settings->{'mao'};
$returner->{'html'} = $c->render_to_string(
template => 'apps/music/configuration',
folders => &Manager::misc_setting_list(),
device => &subs::device_setter(),
mao => eval { return decode_json $jmao } || {},
jmao => $jmao,
settings => $settings,
crate => { remote_uuid => $c->param('remote_uuid') }
);
$c->render(json => $returner);
};
1;

364
President.pl Executable file
View File

@ -0,0 +1,364 @@
#!/usr/bin/perl
use strict;
use warnings;
package President;
print $0 ."\n";
print `pwd` . "\n";
my $self = $$;
print "I am $self\n";
use Mojolicious::Lite;
use Mojo::IOLoop;
use Mojo::Server::Daemon;
use Mojo::Server::Morbo;
use Mojo::Server::Prefork;
use Mojo::Server::Hypnotoad;
use Data::Dumper;
use File::Slurp;
use Time::Local;
use Time::Piece;
use Time::Duration;
use Date::Parse;
use Mojo::JSON qw(decode_json encode_json);
use Mojo::Reactor::Poll;
use threads 'exit' => 'threads_only';
my $working_dir = $0;
my $present_dir = `pwd`;
my $dump_dir = &home('~/.president');
`rm -R $dump_dir/*`;
my $duty_file = &home('~/.president/on_duty');
`touch $duty_file`;
write_file($duty_file, 0);
my $config_file = read_file('./config.json');
my $config = decode_json $config_file;
our $logfile = &home($config->{'logfile'});
`touch $logfile` if not -e $logfile;
our $log = Mojo::Log->new(path => $logfile);
if ($working_dir ne $present_dir) {
my @folder = split '/', $working_dir;
pop @folder;
my $new_dir = join '/', @folder;
print 'chdir to ' . $new_dir . "\n";
chdir $new_dir;
print `pwd` . "\n";
}
#`espeak "president has begun"`;
my $environment = shift;
my $cache_dir = &home('~/') . '.president';
`mkdir -p $cache_dir` unless -e $cache_dir;
require './gb.pl';
$gb::duty_time = &subs::rightNow();
my $random_number = 0;
until ($random_number > 1024 && $random_number < 65532) {
$random_number = int(rand(65532));
}
my $on_duty = 0;
my $hour = localtime( &subs::rightNow() / 1000 )->strftime( "%H");
my $domain = $config->{'domain'} || '127.0.0.1';
#my $domain = '127.0.0.1';
my $device = &device_setter();
if ($device eq 'mobile') {
`termux-wake-lock`;
`sshd`;
}
if ($config->{'open_browser'} eq 'yes') {
if ($device eq 'mobile') {
threads->create(sub() {
`termux-open https://127.0.0.1:$random_number/manager & `
});
}
elsif ($device eq 'computer') {
threads->create(sub() {
`export DISPLAY=:0`;
my $chrome = `chromium https://$domain:$random_number/manager &`;
});
}
}
if ($environment) {
if ($environment =~ /^dev/) {
$config->{'environment'} = 'development';
}
elsif ($environment =~ /^pro/) {
$config->{'environment'} = 'production';
}
}
my $port = $random_number || $config->{'port'};
my $alarm_port = $port + 2;
my $ws_port = $port + 1;
my $dock_port = 3000;
my $tty_port = $port + 3;
if ($config->{'environment'} eq 'development') {
$ws_port = $port;
}
my @threads;
sub manager_starter() {
my $ws_tty_port = $tty_port + 1;
$ENV{PORT_AHOY} = $random_number;
$ENV{PORT_MSG} = $ws_port;
$ENV{PORT_BELL} = $alarm_port;
$ENV{PORT_BESTOW} = $tty_port;
$ENV{PORT_DOCK} = $dock_port;
$ENV{PORT_COMS} = $ws_tty_port;
$ENV{PORT_ENV} = $config->{'environment'};
$ENV{cookie_name} = 'president';
my $certs = "";
if (-e './server/fullchain.pem' && -e './server/privkey.pem') {
$certs = "?cert=./server/fullchain.pem&key=./server/privkey.pem";
}
my $time_count = 0;
write_file($duty_file, &subs::rightNow());
$ENV{'MOJO_MAX_LINE_SIZE'} = "64000";
if ($config->{'environment'} eq 'development') {
threads->create(sub() {
print "Starting Locker Server on port " . $dock_port . "\n";
$ENV{MOJO_LISTEN} = 'https://*:' . $dock_port . $certs;
$ENV{PURPOSE} = 'locker';
my $morbo = Mojo::Server::Morbo->new;
$morbo->backend->watch(['./', './templates']);
$morbo = $morbo->daemon(Mojo::Server::Daemon->new);
$morbo->run('./Manager.pl');
});
if ($ENV{PORT_AHOY} != $ENV{PORT_MSG}) {
threads->create(sub() {
print "Starting WS Server on port " . $ws_port . "\n";
$ENV{MOJO_LISTEN} = 'https://*:' . $ws_port . $certs;
$ENV{PURPOSE} = 'websocket';
my $morbo = Mojo::Server::Morbo->new;
$morbo->backend->watch(['./', './templates']);
$morbo = $morbo->daemon(Mojo::Server::Daemon->new);
$morbo->run('./Manager.pl');
});
}
threads->create(sub() {
print "Starting Main Server on port " . $port . "\n";
$ENV{MOJO_LISTEN} = 'https://*:' . $port . $certs;
$ENV{PURPOSE} = 'main';
my $morbo = Mojo::Server::Morbo->new;
$morbo = $morbo->daemon(Mojo::Server::Daemon->new);
$morbo->backend->watch(['./', './templates']);
$morbo->run('./Manager.pl');
});
}
elsif ($config->{'environment'} eq 'production') {
push @threads, threads->create(sub() {
print "Starting Pro Locker Server on port " . $dock_port . "\n";
$ENV{MOJO_LISTEN} = 'https://*:' . $dock_port . $certs;
$ENV{PURPOSE} = 'locker';
my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]);
$prefork->load_app('./Manager.pl');
$prefork->workers(1);
$prefork->run;
$log->info('after locker server');
});
push @threads, threads->create(sub() {
print "Starting Pro WS Server on port " . $ws_port . "\n";
$ENV{MOJO_LISTEN} = 'https://*:' . $ws_port . $certs;
$ENV{PURPOSE} = 'websocket';
my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]);
$prefork->load_app('./Manager.pl');
$prefork->workers(1);
$prefork->run;
$log->info('after ws server');
});
push @threads, threads->create(sub() {
print "Starting Pro Main Server on port " . $port . "\n";
$ENV{MOJO_LISTEN} = 'https://*:' . $port . $certs;
$ENV{PURPOSE} = 'main';
my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]);
$prefork->load_app('./Manager.pl');
$prefork->workers(7);
$prefork->run;
$log->info('after main server');
});
}
else {
print "I have no environment!\n";
}
if ($device ne 'server') {
threads->create(sub() {
$ENV{PURPOSE} = "watch";
$ENV{MOJO_LISTEN} = 'https://*:' . $alarm_port . $certs;
if ($config->{'environment'} eq 'development') {
print "Starting Development Watch Server on $alarm_port\n";
my $morbo = Mojo::Server::Morbo->new;
$morbo = $morbo->daemon(Mojo::Server::Daemon->new);
$morbo->run('./watch.pl');
}
elsif ($config->{'environment'} eq 'production') {
print "Starting Pro Watch Server on port " . $alarm_port . "\n";
my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]);
$prefork->load_app('./watch.pl');
$prefork->workers(3);
$prefork->run;
}
});
threads->create(sub() {
$ENV{PURPOSE} = "teletype";
$ENV{MOJO_LISTEN} = 'https://*:' . $tty_port . $certs;
if ($config->{'environment'} eq 'development') {
print "Starting Development TTY Server on $tty_port\n";
my $morbo = Mojo::Server::Morbo->new;
$morbo = $morbo->daemon(Mojo::Server::Daemon->new);
$morbo->run('./teletype.pl');
}
elsif ($config->{'environment'} eq 'production') {
print "Starting Pro TTY Server on port " . $tty_port . "\n";
my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]);
$prefork->load_app('./teletype.pl');
$prefork->workers(3);
$prefork->run;
}
});
threads->create(sub() {
$ENV{MOJO_LISTEN} = 'http://*:' . $ws_tty_port ;
if ($config->{'environment'} eq 'development') {
print "Starting Development TTYws Server on $ws_tty_port\n";
my $morbo = Mojo::Server::Morbo->new;
$morbo = $morbo->daemon(Mojo::Server::Daemon->new);
$morbo->run('./teletype.pl');
}
elsif ($config->{'environment'} eq 'production') {
print "Starting Pro TTYws Server on port " . $ws_tty_port . "\n";
my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]);
$prefork->load_app('./teletype.pl');
$prefork->workers(1);
$prefork->run;
}
});
}
print "Starting Alarm Clock\n";
$ENV{PURPOSE} = "alarm";
require './Alarm.pl';
$gb::alarm_running = 0;
$gb::budget_running = 0;
$gb::housekeeping_running = 0;
$gb::clothesline_running = 0;
my $id = Mojo::IOLoop->recurring($gb::timeouts->{'alarm'} => sub () {
if ($gb::alarm_running != 1) {
$gb::alarm_running = 1;
$gb::alarm_running = 0;
}
&Alarm::alarm_clock() if $config->{'environment'} eq 'production';
});
my $big = Mojo::IOLoop->recurring($gb::timeouts->{'budget'} => sub() {
if ($gb::budget_running == 0) {
$gb::budget_running = 1;
$gb::budget_running = &Alarm::budget_watcher();
}
});
if ($device eq 'mobile') {
my $sms = Mojo::IOLoop->recurring($gb::timeouts->{'sms'} => sub() {
my $returner = &subs::sms_list_check();
});
}
my $backups = Mojo::IOLoop->recurring($gb::timeouts->{'backups'} => sub() {
my ($db,$database,$sql) = &subs::database_grabber();
if ($db) {
my $c = app->build_controller;
my $suds = &subs::suds_grabber();
$c->session('suds' => $suds);
$c->param('reason' => 'backup');
if ($suds ne '') {
&subs::backup_now($c);
}
}
});
my $clothes = Mojo::IOLoop->recurring($gb::timeouts->{'clothesline'} => sub() {
if ($gb::clothesline_running == 0) {
$gb::clothesline_running = 1;
&subs::hang_to_dry();
$gb::clothesline_running = 0;
}
});
my $tasks = Mojo::IOLoop->recurring($gb::timeouts->{'tasks'} => sub() {
if ($gb::tasks_running == 0) {
$gb::tasks_running = 1;
$gb::tasks_running = &Alarm::task_checker();
}
});
my $sync = Mojo::IOLoop->recurring($gb::timeouts->{'remote_machine_sync'} => sub() {
if ($gb::syncing == 0) {
$gb::syncing = 1;
my $gimme;
my $hour = localtime( &subs::rightNow() / 1000 )->strftime( "%H");
if ($hour eq 4) {
$gimme = '1d';
}
&subs::remote_machine_negotiator({ gimme => $gimme });
$gb::syncing = 0;
}
});
my $house = Mojo::IOLoop->recurring($gb::timeouts->{'housekeeping'} => sub() {
if ($gb::housekeeping_running == 0) {
$gb::housekeeping_running = 1;
$gb::housekeeping_running = &Alarm::housekeeping();
}
});
Mojo::IOLoop->start;
while (1) {
sleep 1;
}
END {
print "quitting now!\n";
print "They dead\n";
# `./scripts/manager_killer.pl`;
}
}
&manager_starter();
sub home() {
my ($inhabitant) = @_;
my $com = 'echo $HOME';
my $cwd = `$com`;
chomp $cwd;
$inhabitant =~ s/~/$cwd/;
return $inhabitant;
}
sub device_setter() {
my $device = 'computer';
if ($config->{'device'}) {
$device = $config->{'device'};
}
else {
my $uname = `uname -a`;
if ($uname =~ /Android/gi) {
$device = 'mobile';
}
elsif ($uname =~ /Debian/gi) {
$device = 'server';
}
}
return $device;
}

126
README.md Executable file
View File

@ -0,0 +1,126 @@
# Android Installation:
Download and install F-Droid
Install Termux
Install Termux:api
## In Termux:
termux-setup-storage
pkg install openssh termux-api espeak build-essential \
perl tesseract imagemagick zip sqlite sshpass openssh \
curl sox iproute2 libqrencode rsync zbar ffmpeg
ssh-keygen -t rsa -b 4096 -f id_rsa
cpan App::cpanminus
apt install openssl openssl-tool
cpanm Net::SSLeay
cpanm --notest --force Mojolicious::Lite \
WWW::Mechanize Time::Piece Time::Duration \
Date::Parse Hash::Merge Encode Data::Dumper \
File::Find File::Slurp Number::Format \
SQL::Abstract Mojo::SQLite Data::UUID \
Mojolicious::Plugin::RenderFile \
LWP::UserAgent Crypt::Simple File::Type \
HTML::Strip URI::Encode LWP::Protocol::https \
URI::Escape MIME::Base64 Math::Trig List::Util \
File::Monitor Device::SerialPort Barcode::ZBar
cd president
chmod +x President.pl
To run
./President.pl
# Debian Installation
sudo apt update; sudo apt upgrade;
sudo apt install net-tools lib32z1-dev cpanminus \
ssh espeak build-essential zip openssl libssl-dev \
perl tesseract-ocr imagemagick sqlite3 sshpass \
ssh curl sox iproute2 qrencode rsync ffmpeg libbarcode-zbar-perl
sudo cpanm --notest --force Mojolicious::Lite \
WWW::Mechanize Time::Piece Time::Duration \
Date::Parse Hash::Merge Encode Data::Dumper \
File::Find File::Slurp Number::Format \
SQL::Abstract Mojo::SQLite Data::UUID \
Mojolicious::Plugin::RenderFile \
LWP::UserAgent Crypt::Simple File::Type \
HTML::Strip URI::Encode LWP::Protocol::https \
URI::Escape MIME::Base64 Math::Trig \
List::Util Net::SSLeay File::Monitor \
Device::SerialPort Barcode::ZBar
cd president
./President.pl
# Manjaro Installation:
sudo pacman -Syu
sudo pacman -S base-devel cpanminus sqlite3 \
chromium xclip rsync sshpass certbot zip \
imagemagick espeak-ng tesseract xsane sox \
net-tools xdotool qrencode zbar fprintd
sudo cpanm --notest --force Mojolicious::Lite \
WWW::Mechanize Time::Piece Time::Duration \
Date::Parse Hash::Merge Encode Data::Dumper \
File::Find File::Slurp Number::Format \
SQL::Abstract Mojo::SQLite Data::UUID \
Mojolicious::Plugin::RenderFile \
LWP::UserAgent Crypt::Simple File::Type \
HTML::Strip URI::Encode LWP::Protocol::https \
URI::Escape MIME::Base64 Math::Trig \
List::Util Net::SSLeay \
File::Monitor Device::SerialPort Barcode::ZBar
# Alpine Linux
# Haven't really tested this one, except on an iPhone 6 in iSH
apk update
apk upgrade
apk add alpine-sdk perl-app-cpanminus sqlite \
openssh curl net-tools zip libqrencode rsync wget \
zbar
sudo cpanm --notest --force Mojolicious::Lite \
WWW::Mechanize Time::Piece Time::Duration \
Date::Parse Hash::Merge Encode Data::Dumper \
File::Find File::Slurp Number::Format \
SQL::Abstract Mojo::SQLite Data::UUID \
Mojolicious::Plugin::RenderFile \
LWP::UserAgent Crypt::Simple File::Type \
HTML::Strip URI::Encode LWP::Protocol::https \
URI::Escape MIME::Base64 Math::Trig List::Util \
Net::SSLeay File::Monitor Device::SerialPort \
Barcode::ZBar
# POST INSTALL
To access the database, move or copy database/initial.enc to your home directory.
Then copy the config.json.example file to config.json:
cp -v database/initial.enc ~/initial.enc
cp -v config.json.example config.json
cd president
./President.pl
Your default browser should automatically open with the database highlighted.
Password: password
This is alpha software, expect yourself to be frustrated most of the time... the handbook is in progress.

79
Websocket.pl Executable file
View File

@ -0,0 +1,79 @@
#!/usr/bin/perl
use strict;
use warnings;
package Websocket;
use List::Util qw(shuffle);
use Mojo::Util qw/html_unescape term_escape/;
use Time::Duration;
use Date::Parse;
use Time::Piece;
use Crypt::Simple;
use File::Slurp;
use Mojo::JSON qw(decode_json encode_json);
use Data::Dumper;
require "./gb.pl";
require "./subroutines.pl";
my $config_file = read_file('./config.json');
my $config = decode_json $config_file;
our $logfile = &subs::home($config->{'logfile'});
`touch $logfile` if not -e $logfile;
our $log = Mojo::Log->new(path => $logfile);
my $device = &subs::device_setter();
my $home_file = &subs::home('~/') . '.president/ws_watcher';
`touch $home_file` unless -e $home_file;
sub send() {
my ($app,$msg) = @_;
my ($db,$database,$sql) = &subs::database_grabber();
my $returner;
if ($msg->{'console'}) {
if (!$msg->{'whoami'}) {
$msg->{'whoami'} = `whoami`;
chomp $msg->{'whoami'};
}
if (!$msg->{'hostname'}) {
$msg->{'hostname'} = `hostname`;
chomp $msg->{'hostname'};
}
}
my $original_msg = $msg;
if ( eval { encode_json $msg } ) {
my $uuid = &subs::random_string_creator(10);
# $msg->{'uuid'} = $uuid;
$msg->{'formatted_name'} = &subs::format_name($msg->{'app'});
my $m = encode_json $msg;
my $server_time = &subs::rightNow();
if (eval { $sql->db } && $sql->dsn !~ /:$/) {
my $lid = undef;
until ($lid) {
my $success = eval { return &subs::db_insert('websocket_messages', {
origin => $original_msg->{'origin'},
server_time => $server_time,
timestamp => $original_msg->{'timestamp'} || $server_time,
message => $m,
destination => $original_msg->{'destination'} || $original_msg->{'browser_tab_id'},
app => $app,
environment => 'manager',
uuid => $uuid,
patience => $original_msg->{'patience'}
}) };
$lid = $success->last_insert_id;
}
# my $home = &subs::home('~/');
# `echo "$server_time" > $home_file`;
}
}
return $returner;
}
1;

59
config.json Executable file
View File

@ -0,0 +1,59 @@
{
"signatorial": "Jonathan Ferwerda",
"device": "computer",
"birthday": "December 23 1985 9:15am",
"environment": "production",
"production_server": "hypnotoad",
"start_dir": "~/",
"ssh_port": "8022",
"email": "jonathan.ferwerda@outlook.com",
"port": "3000",
"open_browser": "no",
"ws_port": "3001",
"domain": "oldtop.jonathanferwerda.com",
"logfile": "~/manager.log",
"folders": [
"~/Music",
"~/Downloads",
"~/Videos",
"~/Pictures",
"~/Documents",
"~/Recordings",
"/sdcard/Download",
"/sdcard/Documents",
"/sdcard/DCIM",
"/sdcard/Music",
"/sdcard/Pictures",
"/sdcard/Recordings",
"/sdcard/Videos",
"~/storage/shared/Music",
"~/storage/shared/Videos",
"~/storage/shared/Documents",
"~/storage/shared/Download",
"~/storage/shared/DCIM",
"~/storage/shared/Pictures",
"~/storage/shared/Recordings"
],
"scanners": [{
"name": "Officejet LivingRoom",
"address": "hpaio:/net/officejet_3830_series?ip=192.168.0.74",
"resolution": "300",
"feeds": [ "ADF", "Flatbed" ]
}],
"search_engines": [
{ "name": "Google", "url": "https://www.google.com/search?q=" },
{ "name": "DuckDuckGo", "url": "https://duckduckgo.com/?q=" },
{ "name": "Bing", "url": "https://bing.com/?q=", "view":"iframe" },
{ "name": "CTV", "url": "https://www.ctv.ca/search/", "view":"iframe" },
{ "name": "CBC", "url": "https://www.cbc.ca/search?q=", "view":"iframe" },
{ "name": "NP", "url": "https://nationalpost.com/search/?search_text=", "view":"iframe" },
{ "name": "Global", "url": "https://globalnews.ca/?s=", "view":"iframe" },
{ "name": "Sarnia Observer", "url": "https://www.theobserver.ca/search/?search_text=", "view":"iframe" },
{ "name": "LFPress", "url": "https://lfpress.com/search/?search_text=", "view":"iframe" },
{ "name": "Toronto Star", "url": "https://www.thestar.com/search/?q=", "view":"iframe" },
{ "name": "NASA", "url": "https://nasasearch.nasa.gov/search?affiliate=nasa&utf8=✓&query=" },
{ "name": "Wikipedia", "url": "https://en.wikipedia.org/wiki/" },
{ "name": "Kijiji", "url": "https://en.wikipedia.org/wiki/" }
]
}

56
config.json.example Executable file
View File

@ -0,0 +1,56 @@
{
"birthday": "Oct. 1 2022 5pm",
"device": "computer",
"environment": "development",
"start_dir": "~/",
"ssh_port": "8022",
"email": "me@email.com",
"port": "3000",
"open_browser": "yes",
"ws_port": "3001",
"domain": "example.com",
"logfile": "~/manager.log",
"folders": [
"~/Music",
"~/Downloads",
"~/Videos",
"~/Pictures",
"~/Documents",
"~/Recordings",
"/sdcard/Download",
"/sdcard/Documents",
"/sdcard/DCIM",
"/sdcard/Music",
"/sdcard/Pictures",
"/sdcard/Recordings",
"/sdcard/Videos",
"~/storage/shared/Music",
"~/storage/shared/Videos",
"~/storage/shared/Documents",
"~/storage/shared/Download",
"~/storage/shared/DCIM",
"~/storage/shared/Pictures",
"~/storage/shared/Recordings"
],
"scanners": [{
"name": "Officejet LivingRoom",
"address": "hpaio:/net/officejet_3830_series?ip=192.168.0.74",
"resolution": "300",
"feeds": [ "ADF", "Flatbed" ]
}],
"search_engines": [
{ "name": "Google", "url": "https://www.google.com/search?q=" },
{ "name": "DuckDuckGo", "url": "https://duckduckgo.com/?q=" },
{ "name": "Bing", "url": "https://bing.com/?q=", "view":"iframe" },
{ "name": "CTV", "url": "https://www.ctv.ca/search/", "view":"iframe" },
{ "name": "CBC", "url": "https://www.cbc.ca/search?q=", "view":"iframe" },
{ "name": "NP", "url": "https://nationalpost.com/search/?search_text=", "view":"iframe" },
{ "name": "Global", "url": "https://globalnews.ca/?s=", "view":"iframe" },
{ "name": "Sarnia Observer", "url": "https://www.theobserver.ca/search/?search_text=", "view":"iframe" },
{ "name": "LFPress", "url": "https://lfpress.com/search/?search_text=", "view":"iframe" },
{ "name": "Toronto Star", "url": "https://www.thestar.com/search/?q=", "view":"iframe" },
{ "name": "NASA", "url": "https://nasasearch.nasa.gov/search?affiliate=nasa&utf8=✓&query=" },
{ "name": "Wikipedia", "url": "https://en.wikipedia.org/wiki/" },
{ "name": "Kijiji", "url": "https://en.wikipedia.org/wiki/" }
]
}

BIN
database/initial.enc Normal file

Binary file not shown.

1126
gb.pl Executable file

File diff suppressed because it is too large Load Diff

252
hooks.pl Executable file
View File

@ -0,0 +1,252 @@
#!/usr/bin/env perl;
use strict;
use warnings;
use IO::Compress::Gzip qw(gzip);
require "./subroutines.pl";
our $config_file = read_file('./config.json');
our $config = decode_json $config_file;
our $logfile = &subs::home($config->{'logfile'});
`touch $logfile` if not -e $logfile;
our $log = Mojo::Log->new(path => $logfile);
hook before_dispatch => sub {
my ($c) = @_;
my $path = $c->req->url->path;
my $port = $c->req->url->base->port;
my $local_address = $c->tx->local_address;
my $remote_address = $c->tx->remote_address;
if ($local_address ne $remote_address) {
# $log->info($local_address . ' ' . $path . ' ' . $port);
}
$c->session('reject_count', 0) unless $c->session('reject_count');
if ($local_address ne $remote_address) {
my $nl = &subs::db_query('select * from neighbour_link where initiator=? and initiated=? order by server_time desc limit 1', $remote_address, $local_address)->hashes;
if (scalar @{$nl} == 0 && $c->param('my_name') && $c->param('signatorial')) {
my $nlrq = $c->render_to_string(
template => 'configure/neighbour_link_request',
local_address => $local_address,
remote_address => $remote_address,
my_name => $c->param('my_name'),
signatorial => $c->param('signatorial')
);
#$c->render(template => 'guest_layouts/pending', message => '... hold on!');
#$c->session('authentication' => 'pending');
#$c->rendered;
#}
&Websocket::send('server', { alert => $nlrq });
}
elsif ($nl->[0]->{'status'} ne 'blacklisted') {
# $c->session('authentication', $nl->[0]->{'status'});
}
else {
# $c->session('authentication' => 'denial');
}
}
if ($c->session('authentication') eq 'denial') {
my $denial = $c->render(template => 'guest_layouts/denial', message => '... and fuck you too!');
$c->session('authentication' => 'denial');
$c->rendered;
return;
# $c->continue;
}
if ($c->session('authentication') ne 'approved') {
my $total_upload = 0;
my @uploads = @{$c->req->uploads};
foreach my $u ( @uploads ) {
$total_upload += $u->size;
}
if ($total_upload > 10000000 || $c->session('authentication') eq 'fuck you') {
$c->stash('no' => 1);
my $denial = $c->render(template => 'guest_layouts/denial', message => '... and fuck you too!');
$c->session('authentication' => 'fuck you');
&subs::say_it('fuck you! time consumer');
$c->rendered;
}
}
# &subs::log_writer($remote_address . ' ' . $path);
my $allowances = {
guest => [
'/js/mailbox.js',
'/',
'/js/jquery-ui.js',
'/js/jquery.ui.touch-punch.min.js',
'/js/universal.js',
'/js/homepage.js',
'/js/jquery.js',
'/js/numeral.min.js',
'/mail/ws',
'/mail/homepage_form'
],
resident => [
'manager'
],
citizen => [
'/configure',
'/manager/magazine/publish',
]
};
#if ($port eq $ENV{PORT_MAIN} && ($path ne '/') && $path !~ /^\/images\/jbuttons/ && $path ne '/css/store.css' && $path ne '/css/universal.css' && $path ne '/images/decipherable/envelope.png' && $path ne "/images/decipherable/gift.png" && $path ne '/payment' && $path ne '/play' && $path ne '/images/make%20believe/cancel_button.png' && $path ne '/box_office/ticket_request') {
# $c->stash('no' => 1);
#}
if ($c->session('authentication') ne 'approved' && $ENV{PURPOSE} eq 'locker' &&
$path ne '/css/store.css' &&
$path ne '/public_view' &&
$path ne '/css/universal.css' &&
$path ne '/denial' &&
$path !~ /^\/images\/jbuttons/ &&
$path ne '/manager/gate' &&
$path ne '/manager/say_it' &&
$path ne '/images/decipherable/envelope.png' &&
$path ne "/images/decipherable/gift.png" &&
$path ne '/images/make%20believe/cancel_button.png' &&
$path ne '/payment' &&
$path ne '/play' &&
$path ne '/box_office/ticket_request') {
$c->stash('no' => 1);
}
my $privilege = $c->session('privilege');
my @a_loud_thing;
if ($privilege) {
if ((@a_loud_thing = grep { $path =~ $_ } @{$allowances->{'citizen'}}) && $privilege ne 'citizen') {
if (scalar @a_loud_thing == 0) {
$c->stash('no' => 1);
}
}
elsif ((@a_loud_thing = grep { $path =~ $_ } @{$allowances->{'resident'}}) && ($privilege ne 'citizen' && $privilege ne 'resident')) {
if (scalar @a_loud_thing == 0) {
$c->stash('no' => 1);
}
}
elsif ((@a_loud_thing = grep { $path eq $_ } @{$allowances->{'guest'}}) && ($privilege ne 'citizen' && $privilege ne 'resident' && $privilege eq 'guest')) {
if (scalar @a_loud_thing == 0) {
$c->stash('no' => 1);
}
}
}
unless ($c->param('browser_tab_id') || $c->session('browser_tab_id')) {
my $ug = Data::UUID->new;
my $uuid = $ug->create_str();
$c->stash('browser_tab_id' => $uuid );
$c->session('browser_tab_id' => $uuid );
$c->stash('website' => '');
}
else {
my $ug = Data::UUID->new;
my $uuid = $ug->create_str();
$c->stash('browser_tab_id' => $c->session('browser_tab_id'));
$c->session('browser_tab_id' => $uuid);
}
unless ($c->param('browser_tab')) {
my $ug = Data::UUID->new;
my $uuid = $ug->create_str();
$c->stash('browser_tab' => $uuid );
$c->session('browser_tab' => $uuid );
}
else {
$c->stash('browser_tab' => '2');
}
unless ($path eq '/icons/logos/WelcomeLogo.png' ||
$path eq "/image/make%20believe/crown.png" ||
$path eq "/images/make%20believe/lock.png" ||
$path eq '/images/make%20believe/cancel_button.png' ||
$path eq "/images/make%20believe/up.png" ||
$path eq "/images/decipherable/gift.png" ||
$path eq "/images/decipherable/envelope.png" ||
$path =~ '^/images/jbuttons' ||
$path eq '/sesh_check' ||
$path eq '/gate' ||
$path eq '/js/gate.js' ||
$path eq '/js/jquery.js' ||
$path eq '/js/numeral.min.js' ||
$path eq '/js/universal.js' ||
$path eq '/css/universal.css' ||
$path eq '/css/store.css' ||
$path eq '/js/homepage.js' ||
$path eq '/teletype/information' ||
$path =~ '^/box_office' ||
$path eq '/denial' ||
$path eq '/js/jquery.ui.touch-punch.min.js' ||
$path eq '/play' || $path eq '/file_open' ||
$path eq '/payment' ||
$path eq '/box_office/ticket_request' ||
$path =~ '^/public_view' ||
$path eq '/', ) {
my $device = &subs::device_setter();
$c->stash('device' => $device);
$c->stash('string' => $Manager::random_caching_string);
if ($c->param('ws_auth') && $remote_address ne $local_address) {
my $success = 0;
my $wsa = $c->param('ws_auth');
my $pa = &subs::setting_grabber({ app => '__president', setting => 'ws_pa' });
my @ws_auth = split $gb::universal_splitter, &subs::decrypter($pa, $wsa);
if ($remote_address eq $ws_auth[0] && $ws_auth[1] eq &subs::signatorial_designer()) {
$c->session('authentication' => 'approved');
# $c->session('suds' => $c->param('suds'));
# $c->session('server_time' => &subs::rightNow());
$success = 1;
}
if ($success == 0) {
&authentication_passer($c)
}
}
else {
my $man = &authentication_passer($c);
}
}
};
hook after_render => sub {
my ($c, $output, $format) = @_;
# Check if "gzip => 1" has been set in the stash
return unless $c->stash->{gzip};
# Check if user agent accepts gzip compression
return unless ($c->req->headers->accept_encoding // '') =~ /gzip/i;
$c->res->headers->append(Vary => 'Accept-Encoding');
# Compress content with gzip
$c->res->headers->content_encoding('gzip');
gzip $output, \my $compressed;
$$output = $compressed;
};
hook after_dispatch => sub {
my ($c) = @_;
if ($c->res->code == 500) {
foreach my $h (reverse sort @{$c->stash('mojo.log')->{'parent'}->{'history'}} ) {
if (eval { $h->[3]->{'message'} }) {
my $errors = eval { decode_json &subs::setting_grabber({ app => 'terminal', setting => 'errors' }) } || [];
my $uuid = &subs::random_string_creator(12);
my $error = { timestamp => &subs::rightNow, code => $c->res->code, msg => $c->req->url->path . '<br>' . $h->[3]->{'message'}, uuid => $uuid };
push @{$errors}, $error;
my $jerror = encode_json $errors;
&subs::setting_setter({ app => 'terminal', setting => 'errors', value => $jerror });
&Websocket::send('server', { view => 'errors', console => $error, error => $uuid });
}
}
}
};
1;

123
inventory.jawn Executable file
View File

@ -0,0 +1,123 @@
/the empress.png
nurturing and compassionate
/ace of wands.png
the beginning of a journey with a promising outcome.
A hand provides a twig.
/the devil.png
The animal side of it
/the tower.png
He stands, above the chaos and winds.
/four of swords.png
rest
/six of pentacles.png
charity
/four of cups.png
A gift, and the ability to not need it at present
/ace of pentacles.png
New money, the hand is out, now your turn to make it happen
/five of wands.png
Free play
/queen of pentacles.png
Wealth approved!
/ten of cups.png
Family, welcoming, home.
/six of wands.png
Victory!
/the fool.png
Now begin
/ten of swords.png
Resurrection.
Dead for a while, while his enemies hovered over him.
The first beat of life, he's coming back.
/temperance.png
Confidence in the middle road. Chill, calm, cool.
/death.png
the end
/four of pentacles.png
Mind on money, with options.
/five of pentacles.png
Coming alongside to help with money.
/king of wands.png
The way is guided by the Therapist who speaks through the breeze.
/the hermit.png
Alone on his travels, through the deep woods of the subconscious.
Craving company, goes by light to something that calls his heart.
/nine of swords.png
Depression and frustration, stuck in a rutt waiting for something better to happen.
/king of cups.png
Generous, stability of heart, able to rest.
Should be allowed to be annoyed that his trivial pursuits aren't going as intended.
/eight of pentacles.png
Hardwork, tenacity. Secrets of success.
/three of wands.png
A merchant looking out on his investments as they return
/two of wands.png
Looking at the beginning of a new project from the end of it.
The big looks at the little and says, how did I stick to it?
/seven of swords.png
The weapons of those planning to attack are taken, mostly.
The ones left are so they still attempt to invade, ill equipped.
/homefree.png
The end of a journey, all pitfalls accomplished, and the world achieved.
Now time to live peacefully in quiet with a home firmly established.
/ace of cups.png
Filled to overflowing, enough to hydrate, replenish, and this is only the start.
A hand offers wine in a cup from a never ending spring.
/the sun.png
Giver of life.

BIN
jp/alarmclock.ino.bin Executable file

Binary file not shown.

1043
jp/alarmclock/alarmclock.ino Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1602
jt/Final_Frontier_28.h Executable file

File diff suppressed because it is too large Load Diff

3426
jt/Latin_Hiragana_24.h Executable file

File diff suppressed because it is too large Load Diff

694
jt/NotoSansBold15.h Executable file
View File

@ -0,0 +1,694 @@
/* The font vlw file can be converted to a byte array using:
https://tomeko.net/online_tools/file_to_hex.php?lang=en
Paste the byte array into a sketch tab and add two lines
at the start with a unique font name:
const uint8_t fontName[] PROGMEM = {
At the end add:
};
See example below. Include the tab in the main sketch, e.g.:
#include "NotoSansBold15.h"
*/
const uint8_t NotoSansBold15[] PROGMEM = {
0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0B,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x0A,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06,
0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAE, 0xAE, 0x3D,
0x02, 0xFF, 0xFF, 0x52, 0x00, 0xFC, 0xFF, 0x4C, 0x00, 0xF6, 0xFF, 0x48, 0x00, 0xEE, 0xFF, 0x3F,
0x00, 0xD4, 0xFF, 0x15, 0x00, 0xB6, 0xFF, 0x08, 0x00, 0x41, 0x5D, 0x00, 0x00, 0x26, 0x39, 0x00,
0x06, 0xF6, 0xFF, 0x4C, 0x06, 0xEE, 0xFF, 0x3F, 0x00, 0x04, 0x17, 0x00, 0xAC, 0xAC, 0x00, 0xA5,
0xAE, 0x04, 0xF4, 0xF0, 0x00, 0xD6, 0xFC, 0x00, 0xDA, 0xDA, 0x00, 0xB4, 0xF4, 0x00, 0xB4, 0xB2,
0x00, 0xAC, 0xE7, 0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x59, 0xA7, 0x02,
0x48, 0xA7, 0x06, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xEE, 0x00, 0xA3, 0xF4, 0x00, 0x00, 0x00, 0x00,
0x00, 0xDF, 0xAE, 0x00, 0xC9, 0xB6, 0x00, 0x00, 0x08, 0xAE, 0xAE, 0xFF, 0xDF, 0xAE, 0xFC, 0xE1,
0xAE, 0x3B, 0x08, 0xBB, 0xD0, 0xFF, 0xCE, 0xCE, 0xFF, 0xCE, 0xBB, 0x3F, 0x00, 0x00, 0x66, 0xFF,
0x1F, 0x5B, 0xFF, 0x2A, 0x00, 0x00, 0x41, 0x63, 0xC3, 0xFA, 0x63, 0xC1, 0xFC, 0x63, 0x5D, 0x00,
0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x00, 0x00, 0x02, 0xFC, 0x96, 0x02, 0xFC,
0x9D, 0x00, 0x00, 0x00, 0x00, 0x33, 0xFF, 0x57, 0x33, 0xFF, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x57,
0xFF, 0x30, 0x59, 0xFF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x3D, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x6E, 0xC9, 0x44, 0x06, 0x00, 0x00, 0x68, 0xEE, 0xFF, 0xFF, 0xFF, 0xFC, 0x85,
0x30, 0xFF, 0xFF, 0xC3, 0xDF, 0xA1, 0xD8, 0x5F, 0x55, 0xFF, 0xF0, 0x48, 0xB4, 0x00, 0x00, 0x00,
0x17, 0xF2, 0xFF, 0xEB, 0xC9, 0x0C, 0x00, 0x00, 0x00, 0x33, 0xD0, 0xFF, 0xFF, 0xF6, 0x8C, 0x08,
0x00, 0x00, 0x00, 0x6A, 0xF0, 0xFF, 0xFF, 0xAC, 0x02, 0x00, 0x00, 0x44, 0xB4, 0x5B, 0xFF, 0xF8,
0x50, 0xCE, 0x85, 0x83, 0xCE, 0xAE, 0xFF, 0xD6, 0x41, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x35,
0x00, 0x0C, 0x4A, 0x83, 0xCE, 0x44, 0x02, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xA7, 0x00, 0x00, 0x00,
0x00, 0x5D, 0xC9, 0xC7, 0x57, 0x00, 0x00, 0x00, 0x3F, 0xAE, 0x41, 0x00, 0x00, 0x2A, 0xFF, 0xE3,
0xE3, 0xFF, 0x28, 0x00, 0x00, 0xD2, 0xDF, 0x06, 0x00, 0x00, 0x6A, 0xFF, 0x5D, 0x5B, 0xFF, 0x70,
0x00, 0x61, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x94, 0xFF, 0x50, 0x50, 0xFF, 0x94, 0x06, 0xE5, 0xCE,
0x00, 0x00, 0x00, 0x00, 0x63, 0xFF, 0x5B, 0x5B, 0xFF, 0x70, 0x7F, 0xFF, 0x3B, 0x63, 0x9B, 0x59,
0x00, 0x24, 0xFC, 0xE1, 0xE1, 0xFF, 0x41, 0xF4, 0xB0, 0x83, 0xFF, 0xFA, 0xFF, 0x7B, 0x00, 0x52,
0xC7, 0xC7, 0x5D, 0x96, 0xFC, 0x24, 0xE5, 0xF6, 0x08, 0xF6, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x2A,
0xFF, 0x90, 0x00, 0xFF, 0xC5, 0x00, 0xBB, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xF2, 0x13, 0x00,
0xFA, 0xDA, 0x00, 0xD0, 0xFC, 0x00, 0x00, 0x00, 0x41, 0xFF, 0x77, 0x00, 0x00, 0xBD, 0xFC, 0x72,
0xFC, 0xC3, 0x00, 0x00, 0x00, 0xD2, 0xE1, 0x06, 0x00, 0x00, 0x2E, 0xE7, 0xFF, 0xE9, 0x35, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x3D, 0xAC,
0xE1, 0xBB, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0xFA, 0xFF, 0xF0, 0xFC, 0xFF, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0xFF, 0xA7, 0x00, 0x70, 0xFF, 0xA3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x55, 0xFF, 0xC7, 0x0C, 0xBF, 0xFF, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xD4, 0xFF,
0xF4, 0xFF, 0xB2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD6, 0xFF, 0xFF, 0xCC, 0x00, 0x00,
0x72, 0xB4, 0x77, 0x00, 0x0C, 0xE9, 0xFF, 0xB4, 0xE5, 0xFF, 0x94, 0x02, 0xE5, 0xFF, 0x63, 0x00,
0x52, 0xFF, 0xFC, 0x08, 0x1D, 0xE5, 0xFF, 0xD4, 0xFF, 0xDF, 0x02, 0x00, 0x57, 0xFF, 0xFC, 0x1F,
0x00, 0x1D, 0xE7, 0xFF, 0xFF, 0x48, 0x00, 0x00, 0x15, 0xEE, 0xFF, 0xF4, 0xB0, 0xD4, 0xFF, 0xFF,
0xFF, 0xAC, 0x00, 0x00, 0x00, 0x35, 0xCC, 0xFF, 0xFF, 0xFF, 0xC1, 0x57, 0xE1, 0xFF, 0xB0, 0x04,
0x00, 0x00, 0x00, 0x06, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xAC, 0xF4, 0xF0,
0xDA, 0xDA, 0xB4, 0xB2, 0x0C, 0x0C, 0x00, 0x00, 0x4C, 0xAE, 0x46, 0x00, 0x13, 0xEB, 0xDA, 0x02,
0x00, 0x81, 0xFF, 0x68, 0x00, 0x00, 0xE3, 0xFC, 0x0C, 0x00, 0x22, 0xFF, 0xC3, 0x00, 0x00, 0x50,
0xFF, 0xA1, 0x00, 0x00, 0x59, 0xFF, 0x99, 0x00, 0x00, 0x59, 0xFF, 0x99, 0x00, 0x00, 0x4A, 0xFF,
0xA7, 0x00, 0x00, 0x11, 0xFF, 0xDA, 0x00, 0x00, 0x00, 0xCC, 0xFF, 0x22, 0x00, 0x00, 0x63, 0xFF,
0x81, 0x00, 0x00, 0x00, 0xCC, 0xF4, 0x17, 0x00, 0x00, 0x1B, 0x57, 0x28, 0x33, 0xAE, 0x5B, 0x00,
0x00, 0x00, 0xCE, 0xF8, 0x22, 0x00, 0x00, 0x52, 0xFF, 0x96, 0x00, 0x00, 0x02, 0xF6, 0xF4, 0x02,
0x00, 0x00, 0xAE, 0xFF, 0x3D, 0x00, 0x00, 0x96, 0xFF, 0x59, 0x00, 0x00, 0x66, 0xFF, 0x63, 0x00,
0x00, 0x70, 0xFF, 0x61, 0x00, 0x00, 0x9D, 0xFF, 0x57, 0x00, 0x00, 0xC1, 0xFF, 0x2C, 0x00, 0x11,
0xFC, 0xE1, 0x00, 0x00, 0x74, 0xFF, 0x79, 0x00, 0x0C, 0xE7, 0xDD, 0x08, 0x00, 0x1F, 0x57, 0x22,
0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xF2, 0x00,
0x00, 0x00, 0x1B, 0x3F, 0x02, 0xA7, 0xCE, 0x00, 0x2C, 0x2E, 0x5B, 0xFF, 0xF4, 0xE1, 0xE5, 0xE9,
0xFF, 0x9B, 0x2A, 0x61, 0xA1, 0xFF, 0xFF, 0xBB, 0x63, 0x3B, 0x00, 0x00, 0xBB, 0xEB, 0xD8, 0xDA,
0x0C, 0x00, 0x00, 0x6A, 0xFF, 0x81, 0x5B, 0xFF, 0x8E, 0x00, 0x00, 0x00, 0x50, 0x17, 0x00, 0x6A,
0x04, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xF2, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xFF, 0x06,
0x00, 0x00, 0x02, 0x06, 0x06, 0x96, 0xFF, 0x0C, 0x06, 0x06, 0x57, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF2, 0x33, 0x94, 0x94, 0xD4, 0xFF, 0x96, 0x94, 0x8C, 0x00, 0x00, 0x00, 0x94, 0xFF, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x50, 0x02,
0x00, 0x00, 0x00, 0x99, 0xAE, 0x33, 0x02, 0xFC, 0xFA, 0x06, 0x39, 0xFF, 0xA1, 0x00, 0x5F, 0xF2,
0x39, 0x00, 0x8C, 0xF2, 0xF2, 0xF2, 0x52, 0x88, 0xEB, 0xEB, 0xEB, 0x50, 0x00, 0x26, 0x39, 0x00,
0x06, 0xF6, 0xFF, 0x4C, 0x06, 0xEE, 0xFF, 0x3F, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00, 0x00, 0x04,
0xAC, 0xAA, 0x00, 0x00, 0x00, 0x55, 0xFF, 0xA5, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0x46, 0x00, 0x00,
0x17, 0xFC, 0xE5, 0x00, 0x00, 0x00, 0x74, 0xFF, 0x88, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0x28, 0x00,
0x00, 0x30, 0xFF, 0xC9, 0x00, 0x00, 0x00, 0x90, 0xFF, 0x68, 0x00, 0x00, 0x02, 0xEB, 0xFA, 0x11,
0x00, 0x00, 0x4E, 0xFF, 0xAE, 0x00, 0x00, 0x00, 0xB2, 0xFF, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0xC5, 0xE3, 0xA5, 0x26, 0x00, 0x00, 0x83, 0xFF, 0xFF, 0xFA, 0xFF, 0xE9, 0x17, 0x04, 0xFA,
0xFF, 0x50, 0x02, 0xC3, 0xFF, 0x88, 0x4A, 0xFF, 0xF6, 0x00, 0x00, 0x59, 0xFF, 0xD0, 0x5B, 0xFF,
0xD4, 0x00, 0x00, 0x48, 0xFF, 0xF8, 0x63, 0xFF, 0xB4, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x5D, 0xFF,
0xC5, 0x00, 0x00, 0x46, 0xFF, 0xFC, 0x50, 0xFF, 0xF2, 0x00, 0x00, 0x52, 0xFF, 0xE7, 0x0E, 0xFC,
0xFF, 0x26, 0x00, 0x96, 0xFF, 0xA7, 0x00, 0x9F, 0xFF, 0xE3, 0xB4, 0xFF, 0xFF, 0x3F, 0x00, 0x0E,
0xAE, 0xFF, 0xFF, 0xF2, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00,
0x19, 0xA3, 0xAE, 0x2A, 0x00, 0x3F, 0xE9, 0xFF, 0xFF, 0x3D, 0x6E, 0xFC, 0xEE, 0xFF, 0xFF, 0x3D,
0xB4, 0xE1, 0x2E, 0xFF, 0xFF, 0x3D, 0x11, 0x15, 0x06, 0xFF, 0xFF, 0x3D, 0x00, 0x00, 0x06, 0xFF,
0xFF, 0x3D, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x3D, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x3D, 0x00, 0x00,
0x06, 0xFF, 0xFF, 0x3D, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x3D, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x3D,
0x00, 0x17, 0x85, 0xBF, 0xE1, 0xAC, 0x41, 0x00, 0x00, 0x28, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x4A, 0x00, 0x00, 0xB4, 0x99, 0x1F, 0x06, 0xBB, 0xFF, 0xAC, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x72, 0xFF, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xFF, 0x79, 0x00, 0x00, 0x00, 0x00,
0x00, 0x8E, 0xFF, 0xDA, 0x08, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE5, 0x1D, 0x00, 0x00, 0x00,
0x00, 0x7B, 0xFF, 0xDF, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x77, 0xFF, 0xD2, 0x15, 0x00, 0x00, 0x00,
0x00, 0x4A, 0xFF, 0xFF, 0xF6, 0xF2, 0xF2, 0xF2, 0xF2, 0x06, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x06, 0x00, 0x4E, 0xA7, 0xD2, 0xD6, 0xAC, 0x4A, 0x00, 0x2E, 0xFC, 0xFF, 0xFC, 0xFC,
0xFF, 0xFF, 0x50, 0x00, 0x66, 0x46, 0x02, 0x06, 0xC7, 0xFF, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00,
0xA1, 0xFF, 0x8A, 0x00, 0x00, 0x3D, 0x59, 0x8A, 0xFA, 0xCE, 0x13, 0x00, 0x00, 0xB4, 0xFF, 0xFF,
0xE1, 0x41, 0x00, 0x00, 0x00, 0x3D, 0x59, 0x7D, 0xE9, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6A, 0xFF, 0xF4, 0x19, 0x02, 0x00, 0x00, 0x00, 0x8E, 0xFF, 0xE9, 0x5D, 0xF6, 0xAE, 0xA7, 0xC3,
0xFF, 0xFF, 0x81, 0x3D, 0xDD, 0xFF, 0xFF, 0xFF, 0xE7, 0x7B, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xAE, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0xD2, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x35, 0xFF, 0x8C, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x08, 0xD8, 0xDF, 0x1D, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x90, 0xFF, 0x3F, 0x3B, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0x94, 0x00, 0x3D, 0xFF, 0xFF,
0x00, 0x00, 0xB2, 0xFF, 0xFA, 0xF8, 0xFA, 0xFF, 0xFF, 0xF8, 0x4E, 0x7F, 0xB4, 0xB4, 0xB4, 0xC5,
0xFF, 0xFF, 0xB4, 0x39, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x74, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x0C, 0x00, 0xB2,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x13, 0x00, 0xC3, 0xFF, 0x7B, 0x44, 0x44, 0x44, 0x06, 0x00, 0xEE,
0xFF, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0xFF, 0xB6, 0xDD, 0xAC, 0x48, 0x00, 0x00, 0xF4,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x00, 0x13, 0x0C, 0x00, 0x1D, 0xC9, 0xFF, 0xBD, 0x00, 0x00,
0x00, 0x00, 0x00, 0x5F, 0xFF, 0xEB, 0x17, 0x11, 0x00, 0x00, 0x00, 0x9B, 0xFF, 0xBB, 0x4A, 0xFC,
0xC3, 0xAC, 0xCE, 0xFF, 0xFF, 0x50, 0x2E, 0xD8, 0xFF, 0xFF, 0xFF, 0xE1, 0x5B, 0x00, 0x00, 0x00,
0x06, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x68, 0xAC, 0xB8, 0xB8, 0x39, 0x00, 0x00,
0x11, 0xCC, 0xFF, 0xFF, 0xFA, 0xF8, 0x50, 0x00, 0x00, 0x9F, 0xFF, 0xB4, 0x1D, 0x00, 0x00, 0x02,
0x00, 0x0E, 0xFC, 0xF2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF, 0xAA, 0x7D, 0xE9, 0xF0,
0x94, 0x0C, 0x00, 0x5D, 0xFF, 0xF2, 0xF8, 0xBD, 0xFC, 0xFF, 0x9F, 0x00, 0x63, 0xFF, 0xF4, 0x1B,
0x00, 0x57, 0xFF, 0xF8, 0x00, 0x5B, 0xFF, 0xBF, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x06, 0x2A, 0xFF,
0xFA, 0x1D, 0x00, 0x52, 0xFF, 0xF6, 0x00, 0x00, 0xAC, 0xFF, 0xE5, 0xAA, 0xF4, 0xFF, 0x8C, 0x00,
0x00, 0x0C, 0xA1, 0xFC, 0xFF, 0xFC, 0x96, 0x06, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0C, 0x02, 0x00,
0x00, 0x00, 0x6A, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x04, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x04, 0x24, 0x3D, 0x3D, 0x3D, 0x3D, 0x9D, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0xE1, 0xFF, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0xFF, 0xD8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCE, 0xFF, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0xFF, 0xEE, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xFF, 0xFC, 0x1F,
0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFC, 0xFF,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x7F, 0xB4, 0xD4, 0xAC, 0x46, 0x00, 0x00, 0xC1, 0xFF,
0xF6, 0xD0, 0xFF, 0xFF, 0x52, 0x0A, 0xFF, 0xFC, 0x17, 0x00, 0x85, 0xFF, 0xA5, 0x04, 0xFA, 0xFF,
0x2C, 0x00, 0x96, 0xFF, 0x90, 0x00, 0x6E, 0xFF, 0xF2, 0xBF, 0xFF, 0xD4, 0x17, 0x00, 0x08, 0xC5,
0xFF, 0xFF, 0xFA, 0x39, 0x00, 0x04, 0xC7, 0xFF, 0xBD, 0x7F, 0xFC, 0xFC, 0x52, 0x55, 0xFF, 0xC5,
0x00, 0x00, 0x4A, 0xFF, 0xE9, 0x61, 0xFF, 0xB0, 0x00, 0x00, 0x1B, 0xFF, 0xFC, 0x2C, 0xFF, 0xFF,
0xA7, 0x96, 0xD6, 0xFF, 0xB2, 0x00, 0x55, 0xE1, 0xFF, 0xFF, 0xFC, 0x9F, 0x11, 0x00, 0x00, 0x00,
0x0A, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x0C, 0x7F, 0xB4, 0xB6, 0x90, 0x19, 0x00, 0x00, 0xC3, 0xFF,
0xFF, 0xFF, 0xFF, 0xE9, 0x19, 0x4A, 0xFF, 0xF0, 0x28, 0x08, 0xB6, 0xFF, 0x99, 0x79, 0xFF, 0xAA,
0x00, 0x00, 0x4C, 0xFF, 0xEE, 0x6A, 0xFF, 0xBF, 0x00, 0x00, 0x55, 0xFF, 0xFF, 0x37, 0xFF, 0xFF,
0x96, 0x7D, 0xE9, 0xFF, 0xFF, 0x00, 0x83, 0xFF, 0xFF, 0xFF, 0x7B, 0xFF, 0xF2, 0x00, 0x00, 0x1B,
0x4A, 0x22, 0x4C, 0xFF, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x11, 0xCC, 0xFF, 0x5B, 0x00, 0x79, 0xA1,
0xAA, 0xF2, 0xFF, 0xBB, 0x00, 0x00, 0xB4, 0xFF, 0xFF, 0xE9, 0x81, 0x06, 0x00, 0x00, 0x06, 0x0C,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x41, 0x00, 0x06, 0xFA, 0xFF, 0x4E, 0x04, 0xE9, 0xFF,
0x3B, 0x00, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x39,
0x00, 0x06, 0xF6, 0xFF, 0x4C, 0x06, 0xEE, 0xFF, 0x3F, 0x00, 0x04, 0x17, 0x00, 0x00, 0x2E, 0x41,
0x00, 0x06, 0xFA, 0xFF, 0x4E, 0x04, 0xE9, 0xFF, 0x3B, 0x00, 0x04, 0x0A, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0xAE, 0x33, 0x02, 0xFC, 0xFA,
0x06, 0x39, 0xFF, 0xA1, 0x00, 0x5F, 0xF2, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xA7, 0xF2, 0x00, 0x00, 0x00, 0x28, 0xA7, 0xFF, 0xF4,
0x85, 0x00, 0x28, 0xAA, 0xFF, 0xE9, 0x7B, 0x0E, 0x00, 0x48, 0xFF, 0xFF, 0x79, 0x06, 0x00, 0x00,
0x00, 0x1F, 0xAA, 0xFC, 0xFA, 0x9B, 0x35, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x8C, 0xF4, 0xFF, 0xCE,
0x61, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x72, 0xDD, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x46, 0x33, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x8C, 0x57, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF2, 0x02, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x39, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7,
0x9F, 0x52, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xE5, 0x19, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x57, 0xE3, 0x72, 0x06, 0x00, 0x00, 0x00, 0x00, 0x24, 0xC3, 0xFF, 0xE5, 0x72, 0x06, 0x00,
0x00, 0x00, 0x00, 0x35, 0xB0, 0xFF, 0xE7, 0x72, 0x06, 0x00, 0x00, 0x00, 0x00, 0x28, 0xC7, 0xFF,
0xDF, 0x00, 0x00, 0x06, 0x66, 0xCE, 0xFF, 0xE3, 0x77, 0x1B, 0x8E, 0xF2, 0xFF, 0xCE, 0x5D, 0x02,
0x00, 0x57, 0xFF, 0xAE, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x26, 0x88, 0xB8, 0xE5, 0xB4, 0x5F, 0x00, 0xB8, 0xFF, 0xFC, 0xF8, 0xFF, 0xFF, 0x6A, 0x33,
0x5D, 0x04, 0x00, 0x77, 0xFF, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x79, 0xFF, 0xAC, 0x00, 0x00, 0x00,
0x74, 0xFF, 0xF2, 0x2E, 0x00, 0x00, 0x7B, 0xFF, 0xDD, 0x2C, 0x00, 0x00, 0x00, 0xEE, 0xFC, 0x15,
0x00, 0x00, 0x00, 0x00, 0x5B, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x33, 0x00, 0x00, 0x00,
0x00, 0x22, 0xFF, 0xFF, 0x3B, 0x00, 0x00, 0x00, 0x1B, 0xF6, 0xFC, 0x33, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x7F, 0xA5, 0xA7, 0x94, 0x44, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0xA5, 0xFF, 0xE5, 0xB0, 0xAA, 0xD8, 0xFF, 0xBD, 0x15, 0x00, 0x00,
0x02, 0xC3, 0xF2, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x52, 0xF4, 0xC3, 0x00, 0x00, 0x72, 0xFF, 0x4A,
0x15, 0x96, 0xE5, 0xEE, 0xBD, 0x6A, 0x6E, 0xFF, 0x4C, 0x00, 0xE3, 0xBF, 0x02, 0xD4, 0xF2, 0x7D,
0x5F, 0xFF, 0xA3, 0x04, 0xFC, 0x9F, 0x1B, 0xFF, 0x74, 0x55, 0xFF, 0x66, 0x00, 0x06, 0xFF, 0x9D,
0x00, 0xF2, 0xA7, 0x48, 0xFF, 0x57, 0x63, 0xFF, 0x44, 0x00, 0x22, 0xFF, 0x96, 0x00, 0xF8, 0xA1,
0x39, 0xFF, 0x5F, 0x55, 0xFF, 0x6C, 0x00, 0x7B, 0xFF, 0x9D, 0x35, 0xFF, 0x5B, 0x04, 0xFA, 0xA7,
0x02, 0xC3, 0xFF, 0xF2, 0xF8, 0xBB, 0xFF, 0xFA, 0xC5, 0x02, 0x00, 0x9D, 0xFC, 0x39, 0x02, 0x4C,
0x5B, 0x24, 0x00, 0x52, 0x55, 0x06, 0x00, 0x00, 0x15, 0xDD, 0xF6, 0x81, 0x44, 0x0E, 0x37, 0x52,
0x9D, 0x08, 0x00, 0x00, 0x00, 0x00, 0x11, 0x92, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xCE, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x4A, 0x44, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3D, 0xB4, 0xB4, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xFF, 0xFA, 0xF8,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xF6, 0xFA, 0xAA, 0xFF, 0x57, 0x00, 0x00, 0x00, 0x00,
0x00, 0x59, 0xFF, 0xB2, 0x57, 0xFF, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xFF, 0x68, 0x0C,
0xFC, 0xFA, 0x11, 0x00, 0x00, 0x00, 0x0E, 0xFC, 0xFF, 0x1B, 0x00, 0xB8, 0xFF, 0x66, 0x00, 0x00,
0x00, 0x66, 0xFF, 0xE9, 0x63, 0x63, 0xAC, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x00, 0x1D, 0xFF, 0xFF, 0x74, 0x63, 0x63, 0x63, 0xDA, 0xFF, 0x72,
0x00, 0x74, 0xFF, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xFF, 0xCE, 0x00, 0xD0, 0xFF, 0x92, 0x00,
0x00, 0x00, 0x00, 0x3B, 0xFF, 0xFF, 0x26, 0x72, 0xAE, 0xAE, 0xAC, 0xA5, 0x90, 0x3F, 0x00, 0x00,
0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8A, 0x00, 0xA7, 0xFF, 0xA7, 0x13, 0x3B, 0xAC, 0xFF,
0xF8, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x55, 0xFF, 0xF8, 0x00, 0xA7, 0xFF, 0xC5, 0x63, 0x81,
0xDD, 0xFF, 0x8E, 0x00, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x22, 0x00, 0xA7, 0xFF, 0xBF,
0x50, 0x55, 0xB0, 0xFF, 0xE9, 0x06, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0x48, 0xA7,
0xFF, 0xA1, 0x00, 0x00, 0x50, 0xFF, 0xFF, 0x37, 0xA7, 0xFF, 0xF8, 0xEB, 0xEE, 0xFF, 0xFF, 0xC9,
0x00, 0xA7, 0xFF, 0xFF, 0xFF, 0xFC, 0xE5, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xAC, 0xD6,
0xC9, 0xA3, 0x4A, 0x00, 0x00, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x00, 0x59, 0xFF, 0xFF,
0x70, 0x06, 0x0C, 0x61, 0x48, 0x00, 0xC7, 0xFF, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFC,
0xFF, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0xFF, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x72, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x96, 0xFF, 0xE3, 0x19, 0x00, 0x00, 0x02, 0x24, 0x00, 0x1B, 0xE9, 0xFF, 0xFA,
0xB6, 0xB6, 0xF6, 0xA1, 0x00, 0x00, 0x24, 0xBB, 0xFC, 0xFF, 0xFF, 0xF2, 0x6C, 0x00, 0x00, 0x00,
0x00, 0x02, 0x0C, 0x0A, 0x00, 0x00, 0x72, 0xAE, 0xAE, 0xAC, 0xA5, 0x79, 0x24, 0x00, 0x00, 0x00,
0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0x00, 0x00, 0xA7, 0xFF, 0xA7, 0x13, 0x39, 0x85,
0xFF, 0xFF, 0x6A, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x8A, 0xFF, 0xE5, 0x00, 0xA7, 0xFF,
0xA1, 0x00, 0x00, 0x00, 0x3B, 0xFF, 0xFF, 0x22, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x0C, 0xFF,
0xFF, 0x44, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x30, 0xFF, 0xFF, 0x2A, 0xA7, 0xFF, 0xA1, 0x00,
0x00, 0x00, 0x77, 0xFF, 0xF4, 0x02, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x52, 0xF2, 0xFF, 0x88, 0x00,
0xA7, 0xFF, 0xF8, 0xEB, 0xF8, 0xFF, 0xFF, 0xBB, 0x08, 0x00, 0xA7, 0xFF, 0xFF, 0xFC, 0xF2, 0xB6,
0x5F, 0x00, 0x00, 0x00, 0x72, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x66, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x94, 0xA7, 0xFF, 0xA7, 0x13, 0x13, 0x13, 0x0C, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00,
0xA7, 0xFF, 0xD8, 0x94, 0x94, 0x94, 0x2A, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4A, 0xA7, 0xFF,
0xC1, 0x57, 0x57, 0x57, 0x19, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00,
0x00, 0x00, 0x00, 0xA7, 0xFF, 0xF8, 0xEB, 0xEB, 0xEB, 0x88, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x94, 0x72, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x44, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x63, 0xA7,
0xFF, 0xA1, 0x13, 0x13, 0x13, 0x06, 0xA7, 0xFF, 0x9B, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0x9D,
0x06, 0x06, 0x06, 0x02, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x44, 0xA7, 0xFF, 0xE1, 0xB4, 0xB4,
0xB4, 0x30, 0xA7, 0xFF, 0x9B, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0x9B, 0x00, 0x00, 0x00, 0x00,
0xA7, 0xFF, 0x9B, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x99, 0xBD, 0xE5, 0xB6, 0x94, 0x33, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x55, 0x00, 0x52, 0xFF, 0xFF, 0xA7, 0x24, 0x00, 0x1B, 0x6A, 0x02, 0x00, 0xC7, 0xFF, 0xC3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFC, 0xFF, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0C, 0xFF, 0xFF, 0x44, 0x00, 0x9B, 0xFF, 0xFF, 0xFF, 0xA7, 0x06, 0xFF, 0xFF, 0x48, 0x00, 0x8E,
0xEB, 0xF8, 0xFF, 0xA7, 0x00, 0xEB, 0xFF, 0x79, 0x00, 0x00, 0x00, 0x9B, 0xFF, 0xA7, 0x00, 0x94,
0xFF, 0xEB, 0x2A, 0x00, 0x00, 0x9B, 0xFF, 0xA7, 0x00, 0x17, 0xE5, 0xFF, 0xFC, 0xBB, 0xB2, 0xF2,
0xFF, 0xA7, 0x00, 0x00, 0x1D, 0xAA, 0xFC, 0xFF, 0xFF, 0xFF, 0xD6, 0x6A, 0x00, 0x00, 0x00, 0x00,
0x02, 0x0C, 0x0C, 0x02, 0x00, 0x00, 0x72, 0xAE, 0x6E, 0x00, 0x00, 0x00, 0x08, 0xAE, 0xAE, 0x08,
0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00,
0x0C, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF,
0xD8, 0x94, 0x94, 0x94, 0x99, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x0C, 0xA7, 0xFF, 0xC1, 0x57, 0x57, 0x57, 0x5F, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF, 0xA1, 0x00,
0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x0C,
0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x0C, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00,
0x0C, 0xFF, 0xFF, 0x0C, 0x66, 0xAE, 0xAE, 0xAE, 0xAE, 0x3B, 0x61, 0xF8, 0xFF, 0xFF, 0xE9, 0x39,
0x00, 0x48, 0xFF, 0xFF, 0x06, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x44,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x00, 0x00, 0x35, 0xC3, 0xFF, 0xFF, 0xAA, 0x1D,
0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0x57, 0x00, 0x00, 0x00, 0x72, 0xAE, 0x6E, 0x00, 0x00, 0x00, 0xA7,
0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00,
0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1,
0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7,
0xFF, 0xA1, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0x9D, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0x7D, 0x0C, 0xBF,
0xD6, 0xFF, 0xFF, 0x2C, 0x0C, 0xFF, 0xFF, 0xEB, 0x5F, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x00,
0x72, 0xAE, 0x6E, 0x00, 0x00, 0x00, 0x94, 0xAE, 0x6E, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x85, 0xFF,
0xE3, 0x15, 0xA7, 0xFF, 0xA1, 0x00, 0x50, 0xFF, 0xF8, 0x33, 0x00, 0xA7, 0xFF, 0xA1, 0x28, 0xF2,
0xFF, 0x5F, 0x00, 0x00, 0xA7, 0xFF, 0xAA, 0xD6, 0xFF, 0x96, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xFC,
0xFF, 0xFF, 0x77, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xFF, 0xB6, 0xFF, 0xF8, 0x22, 0x00, 0x00, 0xA7,
0xFF, 0xA1, 0x00, 0xC5, 0xFF, 0xBB, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x2A, 0xFC, 0xFF, 0x59,
0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x85, 0xFF, 0xE9, 0x13, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x08,
0xDF, 0xFF, 0x9B, 0x72, 0xAE, 0x6E, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00,
0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA7,
0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1,
0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00,
0x00, 0x00, 0xA7, 0xFF, 0xF8, 0xEB, 0xEB, 0xEB, 0xE5, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x72, 0xAE, 0xAE, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x41, 0xAE, 0xAE, 0x7B, 0xA7, 0xFF, 0xFF, 0xCC,
0x00, 0x00, 0x00, 0x00, 0xAE, 0xFF, 0xFF, 0xB4, 0xA7, 0xFF, 0xF6, 0xFF, 0x1B, 0x00, 0x00, 0x04,
0xFA, 0xF6, 0xFF, 0xB4, 0xA7, 0xFF, 0xB2, 0xFF, 0x68, 0x00, 0x00, 0x57, 0xFF, 0xB2, 0xFF, 0xB4,
0xA7, 0xFF, 0x6A, 0xFF, 0xB6, 0x00, 0x00, 0xA7, 0xFC, 0x63, 0xFF, 0xB4, 0xA7, 0xFF, 0x57, 0xCC,
0xFA, 0x08, 0x04, 0xFA, 0xC1, 0x50, 0xFF, 0xB4, 0xA7, 0xFF, 0x57, 0x7F, 0xFF, 0x57, 0x52, 0xFF,
0x6A, 0x50, 0xFF, 0xB4, 0xA7, 0xFF, 0x57, 0x2C, 0xFF, 0xA7, 0xA5, 0xFF, 0x1B, 0x50, 0xFF, 0xB4,
0xA7, 0xFF, 0x57, 0x00, 0xDF, 0xF6, 0xF6, 0xC3, 0x00, 0x50, 0xFF, 0xB4, 0xA7, 0xFF, 0x57, 0x00,
0x90, 0xFF, 0xFF, 0x72, 0x00, 0x50, 0xFF, 0xB4, 0xA7, 0xFF, 0x57, 0x00, 0x41, 0xFF, 0xFF, 0x1D,
0x00, 0x50, 0xFF, 0xB4, 0x72, 0xAE, 0xAE, 0x48, 0x00, 0x00, 0x00, 0x2A, 0xAE, 0x9D, 0xA7, 0xFF,
0xFF, 0xDD, 0x06, 0x00, 0x00, 0x3D, 0xFF, 0xE5, 0xA7, 0xFF, 0xFF, 0xFF, 0x77, 0x00, 0x00, 0x3D,
0xFF, 0xE5, 0xA7, 0xFF, 0xA1, 0xFF, 0xF4, 0x19, 0x00, 0x3D, 0xFF, 0xE5, 0xA7, 0xFF, 0x4C, 0xC3,
0xFF, 0x9F, 0x00, 0x3D, 0xFF, 0xE5, 0xA7, 0xFF, 0x52, 0x30, 0xFF, 0xFF, 0x33, 0x3D, 0xFF, 0xE5,
0xA7, 0xFF, 0x57, 0x00, 0x99, 0xFF, 0xCE, 0x1D, 0xFF, 0xE5, 0xA7, 0xFF, 0x57, 0x00, 0x15, 0xF2,
0xFF, 0x6A, 0xFF, 0xE5, 0xA7, 0xFF, 0x57, 0x00, 0x00, 0x77, 0xFF, 0xEB, 0xFF, 0xE5, 0xA7, 0xFF,
0x57, 0x00, 0x00, 0x02, 0xDA, 0xFF, 0xFF, 0xE5, 0xA7, 0xFF, 0x57, 0x00, 0x00, 0x00, 0x4C, 0xFF,
0xFF, 0xE5, 0x00, 0x00, 0x00, 0x5F, 0xAC, 0xE3, 0xE1, 0xAC, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0x00, 0x00, 0x00, 0x72, 0xFF, 0xFF, 0x6A, 0x04,
0x04, 0x72, 0xFF, 0xFF, 0x5D, 0x00, 0x00, 0xD6, 0xFF, 0x9D, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xFF,
0xC1, 0x00, 0x02, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xF8, 0x00, 0x0C, 0xFF,
0xFF, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF, 0xFF, 0x02, 0x06, 0xFF, 0xFF, 0x4C, 0x00, 0x00,
0x00, 0x00, 0x57, 0xFF, 0xFC, 0x00, 0x00, 0xE9, 0xFF, 0x83, 0x00, 0x00, 0x00, 0x00, 0x90, 0xFF,
0xD4, 0x00, 0x00, 0x8C, 0xFF, 0xEE, 0x28, 0x00, 0x00, 0x2C, 0xF2, 0xFF, 0x7D, 0x00, 0x00, 0x11,
0xDF, 0xFF, 0xFC, 0xBF, 0xC3, 0xFC, 0xFF, 0xD6, 0x0C, 0x00, 0x00, 0x00, 0x15, 0xA1, 0xFA, 0xFF,
0xFF, 0xFA, 0x96, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0C, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x72, 0xAE, 0xAE, 0xAC, 0xA5, 0x7B, 0x15, 0x00, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE9, 0x1D, 0xA7, 0xFF, 0xA7, 0x13, 0x50, 0xE7, 0xFF, 0x90, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x9D,
0xFF, 0xAE, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0xC3, 0xFF, 0xA5, 0xA7, 0xFF, 0xDF, 0xAA, 0xDA, 0xFF,
0xFF, 0x3F, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x5D, 0x00, 0xA7, 0xFF, 0xB8, 0x3B, 0x0C, 0x00,
0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00,
0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0xAC, 0xE3,
0xE1, 0xAC, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7,
0x00, 0x00, 0x00, 0x72, 0xFF, 0xFF, 0x6A, 0x04, 0x04, 0x72, 0xFF, 0xFF, 0x5D, 0x00, 0x00, 0xD6,
0xFF, 0x9D, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xFF, 0xC1, 0x00, 0x02, 0xFF, 0xFF, 0x50, 0x00, 0x00,
0x00, 0x00, 0x5D, 0xFF, 0xF8, 0x00, 0x0C, 0xFF, 0xFF, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF,
0xFF, 0x02, 0x06, 0xFF, 0xFF, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x57, 0xFF, 0xFC, 0x00, 0x00, 0xE9,
0xFF, 0x83, 0x00, 0x00, 0x00, 0x00, 0x90, 0xFF, 0xD4, 0x00, 0x00, 0x8C, 0xFF, 0xEE, 0x28, 0x00,
0x00, 0x2C, 0xF2, 0xFF, 0x81, 0x00, 0x00, 0x11, 0xDF, 0xFF, 0xFC, 0xBF, 0xC3, 0xFC, 0xFF, 0xD8,
0x0E, 0x00, 0x00, 0x00, 0x15, 0xA1, 0xFA, 0xFF, 0xFF, 0xFF, 0xC5, 0x15, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x0C, 0x8E, 0xFF, 0xF4, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xBB, 0xFF, 0xE9, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x92, 0x94,
0x77, 0x00, 0x72, 0xAE, 0xAE, 0xAA, 0xA5, 0x70, 0x17, 0x00, 0x00, 0xA7, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xEB, 0x26, 0x00, 0xA7, 0xFF, 0xA7, 0x1F, 0x4E, 0xE3, 0xFF, 0x9D, 0x00, 0xA7, 0xFF, 0xA1,
0x00, 0x00, 0x9B, 0xFF, 0xB0, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x1B, 0xD4, 0xFF, 0x8C, 0x00, 0xA7,
0xFF, 0xFC, 0xF8, 0xFF, 0xFF, 0xD0, 0x13, 0x00, 0xA7, 0xFF, 0xF8, 0xEE, 0xFF, 0xEE, 0x08, 0x00,
0x00, 0xA7, 0xFF, 0xA1, 0x00, 0xC5, 0xFF, 0x85, 0x00, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x2A, 0xFC,
0xFC, 0x33, 0x00, 0xA7, 0xFF, 0xA1, 0x00, 0x00, 0x85, 0xFF, 0xD6, 0x06, 0xA7, 0xFF, 0xA1, 0x00,
0x00, 0x08, 0xDF, 0xFF, 0x8C, 0x00, 0x04, 0x79, 0xBB, 0xE5, 0xB6, 0x81, 0x24, 0x00, 0xAC, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x11, 0xFF, 0xFF, 0x48, 0x02, 0x2A, 0x7B, 0x02, 0x28, 0xFF, 0xFF,
0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xFF, 0xEB, 0x72, 0x08, 0x00, 0x00, 0x00, 0x2A, 0xDD,
0xFF, 0xFF, 0xE7, 0x4E, 0x00, 0x00, 0x00, 0x06, 0x70, 0xE5, 0xFF, 0xFF, 0x3B, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xC9, 0xFF, 0xA1, 0x2C, 0x44, 0x00, 0x00, 0x00, 0xAC, 0xFF, 0xA1, 0x50, 0xFF, 0xEE,
0xB0, 0xC3, 0xFF, 0xFF, 0x46, 0x2E, 0xCE, 0xFF, 0xFF, 0xFF, 0xE3, 0x5D, 0x00, 0x00, 0x00, 0x02,
0x0C, 0x0A, 0x00, 0x00, 0x00, 0x77, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x3B, 0xAE, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x57, 0x2A, 0x3D, 0x3D, 0xC5, 0xFF, 0x88, 0x3D, 0x3D, 0x15,
0x00, 0x00, 0x00, 0xB4, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xFF, 0x63, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xFF,
0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xB4, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xB4, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x77, 0xAE, 0x66, 0x00, 0x00, 0x00, 0x2E, 0xAE,
0xAE, 0x04, 0xAE, 0xFF, 0x94, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x06, 0xAE, 0xFF, 0x94, 0x00,
0x00, 0x00, 0x44, 0xFF, 0xFF, 0x06, 0xAE, 0xFF, 0x94, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x06,
0xAE, 0xFF, 0x94, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x06, 0xAE, 0xFF, 0x94, 0x00, 0x00, 0x00,
0x44, 0xFF, 0xFF, 0x06, 0xAE, 0xFF, 0x94, 0x00, 0x00, 0x00, 0x44, 0xFF, 0xFF, 0x06, 0xAC, 0xFF,
0x9B, 0x00, 0x00, 0x00, 0x4A, 0xFF, 0xFF, 0x02, 0x83, 0xFF, 0xDF, 0x11, 0x00, 0x00, 0x9B, 0xFF,
0xDA, 0x00, 0x19, 0xEE, 0xFF, 0xF6, 0xB4, 0xDA, 0xFF, 0xFF, 0x59, 0x00, 0x00, 0x2A, 0xC3, 0xFF,
0xFF, 0xFF, 0xDA, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
0x96, 0xAE, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x72, 0xAE, 0x6E, 0x92, 0xFF, 0xA7, 0x00, 0x00, 0x00,
0x00, 0xE7, 0xFF, 0x52, 0x3D, 0xFF, 0xF6, 0x02, 0x00, 0x00, 0x3B, 0xFF, 0xF8, 0x04, 0x00, 0xE3,
0xFF, 0x4C, 0x00, 0x00, 0x8C, 0xFF, 0xA3, 0x00, 0x00, 0x8E, 0xFF, 0x9D, 0x00, 0x00, 0xDA, 0xFF,
0x4E, 0x00, 0x00, 0x39, 0xFF, 0xE9, 0x00, 0x2C, 0xFF, 0xF2, 0x02, 0x00, 0x00, 0x00, 0xE1, 0xFF,
0x3D, 0x7F, 0xFF, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xFF, 0x83, 0xC3, 0xFF, 0x48, 0x00, 0x00,
0x00, 0x00, 0x35, 0xFF, 0xC1, 0xFC, 0xEE, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xFF, 0xFF,
0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xFF, 0xFF, 0x41, 0x00, 0x00, 0x00, 0xA1, 0xAE,
0x37, 0x00, 0x00, 0x00, 0x9F, 0xAE, 0x3F, 0x00, 0x00, 0x00, 0x8A, 0xAE, 0x3F, 0xAC, 0xFF, 0x7F,
0x00, 0x00, 0x19, 0xFF, 0xFF, 0xA1, 0x00, 0x00, 0x02, 0xFA, 0xFF, 0x2E, 0x6A, 0xFF, 0xB4, 0x00,
0x00, 0x57, 0xFF, 0xFF, 0xE3, 0x00, 0x00, 0x3F, 0xFF, 0xF2, 0x00, 0x28, 0xFF, 0xF6, 0x00, 0x00,
0xA5, 0xFF, 0xC7, 0xFF, 0x24, 0x00, 0x74, 0xFF, 0xA7, 0x00, 0x00, 0xEB, 0xFF, 0x35, 0x00, 0xE7,
0xF4, 0x6A, 0xFF, 0x66, 0x00, 0xAC, 0xFF, 0x68, 0x00, 0x00, 0xA7, 0xFF, 0x6A, 0x26, 0xFF, 0xAC,
0x3B, 0xFF, 0xA7, 0x00, 0xF4, 0xFF, 0x2A, 0x00, 0x00, 0x63, 0xFF, 0xA7, 0x63, 0xFF, 0x70, 0x02,
0xF6, 0xEE, 0x28, 0xFF, 0xEB, 0x00, 0x00, 0x00, 0x26, 0xFF, 0xE3, 0xA3, 0xFF, 0x33, 0x00, 0xAE,
0xFF, 0x79, 0xFF, 0xA7, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xFF, 0xCE, 0xF6, 0x00, 0x00, 0x6E, 0xFF,
0xE5, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0xA5, 0xFF, 0xFF, 0xAA, 0x00, 0x00, 0x30, 0xFF, 0xFF,
0xFF, 0x28, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xFF, 0x68, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xE7,
0x00, 0x00, 0x00, 0x5B, 0xAE, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x99, 0xAE, 0x59, 0x13, 0xE9, 0xFF,
0x72, 0x00, 0x00, 0x61, 0xFF, 0xE7, 0x0E, 0x00, 0x57, 0xFF, 0xF0, 0x17, 0x0C, 0xE7, 0xFF, 0x52,
0x00, 0x00, 0x00, 0xB2, 0xFF, 0xA5, 0x8A, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xF2, 0xFF,
0xFF, 0xF4, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xFF, 0xFF, 0x85, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1D, 0xF2, 0xFF, 0xFF, 0xE7, 0x13, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0x90, 0xBD, 0xFF,
0xA5, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xE5, 0x0C, 0x22, 0xF8, 0xFF, 0x50, 0x00, 0x15, 0xEB, 0xFF,
0x57, 0x00, 0x00, 0x7F, 0xFF, 0xE9, 0x13, 0xA7, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0x06, 0xDD, 0xFF,
0xA5, 0x8A, 0xAE, 0x6A, 0x00, 0x00, 0x00, 0x2A, 0xAE, 0xAE, 0x19, 0x55, 0xFF, 0xF6, 0x15, 0x00,
0x00, 0xAC, 0xFF, 0xB0, 0x00, 0x00, 0xCE, 0xFF, 0x88, 0x00, 0x2C, 0xFF, 0xFC, 0x28, 0x00, 0x00,
0x3D, 0xFF, 0xF8, 0x19, 0xAE, 0xFF, 0x96, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0xB8, 0xFF, 0xF6,
0x19, 0x00, 0x00, 0x00, 0x00, 0x2C, 0xFF, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xA1, 0xFF, 0xEB, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xBB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF,
0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x48,
0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x2A, 0x6A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x33, 0x1B, 0x3D, 0x3D, 0x3D, 0x3D, 0xDD, 0xFF, 0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFF,
0xE5, 0x13, 0x00, 0x00, 0x00, 0x00, 0x26, 0xF6, 0xFF, 0x44, 0x00, 0x00, 0x00, 0x00, 0x02, 0xCE,
0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xFF, 0xD6, 0x08, 0x00, 0x00, 0x00, 0x00, 0x37,
0xFF, 0xFC, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xDD, 0xFF, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00,
0x88, 0xFF, 0xFF, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0x4A, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x50, 0xAA, 0xAE, 0xAE, 0x6A, 0xF8, 0xFC, 0xBB, 0x72, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xFA,
0x3D, 0x24, 0xF8, 0xFF, 0xFF, 0x9B, 0x55, 0x57, 0x57, 0x35, 0x81, 0xAE, 0x26, 0x00, 0x00, 0x00,
0x70, 0xFF, 0x88, 0x00, 0x00, 0x00, 0x15, 0xFC, 0xE5, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xFF, 0x46,
0x00, 0x00, 0x00, 0x52, 0xFF, 0xA5, 0x00, 0x00, 0x00, 0x02, 0xEE, 0xFA, 0x0C, 0x00, 0x00, 0x00,
0x92, 0xFF, 0x66, 0x00, 0x00, 0x00, 0x37, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xFF, 0x26,
0x00, 0x00, 0x00, 0x79, 0xFF, 0x85, 0x00, 0x00, 0x00, 0x19, 0xFC, 0xE3, 0x6E, 0xAE, 0xAE, 0xA5,
0x77, 0xBB, 0xFC, 0xF2, 0x00, 0x00, 0xF8, 0xF2, 0x00, 0x00, 0xF8, 0xF2, 0x00, 0x00, 0xF8, 0xF2,
0x00, 0x00, 0xF8, 0xF2, 0x00, 0x00, 0xF8, 0xF2, 0x00, 0x00, 0xF8, 0xF2, 0x00, 0x00, 0xF8, 0xF2,
0x00, 0x00, 0xF8, 0xF2, 0x00, 0x00, 0xF8, 0xF2, 0x26, 0x3D, 0xFA, 0xF2, 0xA1, 0xFF, 0xFF, 0xF2,
0x37, 0x57, 0x57, 0x52, 0x00, 0x00, 0x00, 0x6E, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0xF2, 0xFF, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xFC, 0xDD, 0xC7, 0x00, 0x00, 0x00, 0x00,
0x04, 0xE5, 0xAA, 0x59, 0xFF, 0x48, 0x00, 0x00, 0x00, 0x68, 0xFF, 0x35, 0x00, 0xD8, 0xD2, 0x00,
0x00, 0x00, 0xD8, 0xC9, 0x00, 0x00, 0x59, 0xFF, 0x55, 0x00, 0x50, 0xFF, 0x5D, 0x00, 0x00, 0x00,
0xD8, 0xD8, 0x00, 0x28, 0x3D, 0x02, 0x00, 0x00, 0x00, 0x22, 0x3D, 0x0C, 0xA7, 0xA7, 0xA7, 0xA7,
0xA7, 0xA7, 0x28, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x15, 0x17, 0x63, 0x63, 0x1B, 0x00, 0x00,
0x72, 0xFF, 0xC7, 0x04, 0x00, 0x00, 0x41, 0xE1, 0x88, 0x00, 0x00, 0x08, 0x4A, 0x50, 0x4A, 0x04,
0x00, 0x00, 0x55, 0xFA, 0xFF, 0xFF, 0xFF, 0xE9, 0x39, 0x00, 0x15, 0xB8, 0x63, 0x50, 0xB6, 0xFF,
0xC3, 0x00, 0x00, 0x00, 0x00, 0x04, 0x50, 0xFF, 0xF2, 0x00, 0x4A, 0xC3, 0xFA, 0xFF, 0xFF, 0xFF,
0xF2, 0x26, 0xFF, 0xFF, 0x8A, 0x4A, 0x7B, 0xFF, 0xF2, 0x57, 0xFF, 0xF6, 0x00, 0x00, 0x68, 0xFF,
0xF2, 0x3B, 0xFF, 0xFF, 0x9B, 0x90, 0xF2, 0xFF, 0xF2, 0x00, 0x92, 0xFF, 0xFF, 0xE9, 0x4A, 0xCE,
0xF2, 0x00, 0x00, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x44, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00,
0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00,
0x00, 0xBB, 0xFF, 0x59, 0x19, 0x4E, 0x39, 0x00, 0x00, 0xBB, 0xFF, 0x9B, 0xF4, 0xFF, 0xFF, 0xB0,
0x00, 0xBB, 0xFF, 0xF6, 0x7F, 0x88, 0xFF, 0xFF, 0x63, 0xBB, 0xFF, 0x90, 0x00, 0x00, 0xAC, 0xFF,
0xAA, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF, 0xB6, 0xBB, 0xFF, 0x5F, 0x00, 0x00, 0x77, 0xFF,
0xB4, 0xBB, 0xFF, 0xB2, 0x00, 0x00, 0xC5, 0xFF, 0xA3, 0xBB, 0xFF, 0xFF, 0xBF, 0xC5, 0xFF, 0xFF,
0x44, 0xBB, 0xFA, 0x4E, 0xE5, 0xFF, 0xFA, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x33, 0x50, 0x4C, 0x11, 0x00, 0x00, 0x19, 0xCE, 0xFF, 0xFF, 0xFF, 0xFC,
0x13, 0x00, 0xC9, 0xFF, 0xDA, 0x6E, 0x92, 0x9D, 0x00, 0x26, 0xFF, 0xFF, 0x2A, 0x00, 0x00, 0x00,
0x00, 0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0x00,
0x00, 0x24, 0xFF, 0xFF, 0x48, 0x00, 0x00, 0x1B, 0x00, 0x00, 0xC3, 0xFF, 0xF4, 0xAC, 0xB4, 0xF6,
0x00, 0x00, 0x17, 0xB2, 0xFC, 0xFF, 0xFF, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0C, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5D, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF2, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x50, 0x00, 0x00, 0x0E, 0x4E,
0x44, 0x00, 0xF0, 0xFF, 0x50, 0x00, 0x3D, 0xF0, 0xFF, 0xFF, 0xC7, 0xD2, 0xFF, 0x50, 0x00, 0xE1,
0xFF, 0xDA, 0x72, 0xC3, 0xFF, 0xFF, 0x50, 0x33, 0xFF, 0xFF, 0x2A, 0x00, 0x06, 0xF6, 0xFF, 0x50,
0x4E, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0xB6, 0xFF, 0x50, 0x4E, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xBB,
0xFF, 0x50, 0x26, 0xFF, 0xFF, 0x37, 0x00, 0x0E, 0xFA, 0xFF, 0x50, 0x00, 0xCC, 0xFF, 0xEE, 0xA5,
0xD8, 0xFA, 0xFF, 0x50, 0x00, 0x1D, 0xD6, 0xFF, 0xFC, 0x85, 0x90, 0xFF, 0x50, 0x00, 0x00, 0x00,
0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x50, 0x3F, 0x02, 0x00, 0x00, 0x00,
0x19, 0xCE, 0xFF, 0xFF, 0xFF, 0xDD, 0x26, 0x00, 0x00, 0xBF, 0xFF, 0xAA, 0x4C, 0x90, 0xFF, 0xD0,
0x00, 0x24, 0xFF, 0xFF, 0x0E, 0x00, 0x00, 0xF4, 0xFF, 0x1D, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x44, 0x4C, 0xFF, 0xF8, 0x63, 0x63, 0x63, 0x63, 0x63, 0x1B, 0x1B, 0xFF, 0xFF, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xFF, 0xE9, 0x9B, 0x96, 0xAA, 0xAE, 0x00, 0x00, 0x04,
0x8A, 0xF4, 0xFF, 0xFF, 0xFA, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x13, 0x57, 0x63, 0x57, 0x17, 0x00, 0x17, 0xE9, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x5D,
0xFF, 0xF0, 0x57, 0x5B, 0x00, 0x00, 0x6C, 0xFF, 0xC5, 0x3D, 0x2A, 0x00, 0x81, 0xFF, 0xFF, 0xFF,
0xFF, 0xAE, 0x00, 0x44, 0xA1, 0xFF, 0xD2, 0x63, 0x44, 0x00, 0x00, 0x63, 0xFF, 0xB4, 0x00, 0x00,
0x00, 0x00, 0x63, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x63, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00,
0x63, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x63, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x63, 0xFF,
0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x4E, 0x44, 0x00, 0x24, 0x3D, 0x13, 0x00, 0x3D, 0xF0,
0xFF, 0xFF, 0xC7, 0xB6, 0xFF, 0x50, 0x00, 0xDD, 0xFF, 0xD6, 0x74, 0xC3, 0xFF, 0xFF, 0x50, 0x30,
0xFF, 0xFF, 0x28, 0x00, 0x02, 0xF2, 0xFF, 0x50, 0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0xB6, 0xFF,
0x50, 0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0xB4, 0xFF, 0x50, 0x24, 0xFF, 0xFF, 0x35, 0x00, 0x06,
0xF0, 0xFF, 0x50, 0x00, 0xCC, 0xFF, 0xE9, 0xA3, 0xD2, 0xFF, 0xFF, 0x50, 0x00, 0x24, 0xD6, 0xFF,
0xFC, 0x88, 0xF0, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0xF6, 0xFF, 0x4C, 0x00, 0x5D,
0x44, 0x08, 0x04, 0x68, 0xFF, 0xFA, 0x13, 0x00, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x00,
0x00, 0x33, 0x6A, 0x99, 0x9B, 0x70, 0x26, 0x00, 0x00, 0x44, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00,
0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00,
0x00, 0xBB, 0xFF, 0x59, 0x15, 0x4E, 0x48, 0x02, 0x00, 0xBB, 0xFF, 0x96, 0xF4, 0xFF, 0xFF, 0xDF,
0x1D, 0xBB, 0xFF, 0xFF, 0x8A, 0x77, 0xF2, 0xFF, 0x90, 0xBB, 0xFF, 0xA5, 0x00, 0x00, 0x9D, 0xFF,
0xAE, 0xBB, 0xFF, 0x5F, 0x00, 0x00, 0x6E, 0xFF, 0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF,
0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF, 0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF,
0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF, 0xAE, 0x2C, 0x55, 0x0C, 0xE5, 0xFF, 0x77, 0x7B,
0xB2, 0x2E, 0x2E, 0x3D, 0x17, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF,
0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x2C,
0x55, 0x0C, 0x00, 0x00, 0xE5, 0xFF, 0x77, 0x00, 0x00, 0x7B, 0xB2, 0x2E, 0x00, 0x00, 0x2E, 0x3D,
0x17, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xBB, 0xFF, 0x5D,
0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00,
0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xCC, 0xFF, 0x5D, 0x48, 0x52,
0xFA, 0xFF, 0x50, 0xF8, 0xFF, 0xFF, 0xE1, 0x08, 0x79, 0x9B, 0x72, 0x13, 0x00, 0x44, 0x5D, 0x22,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB,
0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x1B, 0x3D, 0x3D,
0x02, 0xBB, 0xFF, 0x5D, 0x00, 0x1F, 0xE7, 0xFF, 0x72, 0x00, 0xBB, 0xFF, 0x5D, 0x15, 0xDD, 0xFF,
0x88, 0x00, 0x00, 0xBB, 0xFF, 0x5F, 0xCC, 0xFF, 0x9D, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0xDF, 0xFF,
0xFC, 0x0E, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0xFF, 0xE1, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0xBB, 0xFF,
0x7F, 0x1B, 0xEE, 0xFF, 0x68, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x52, 0xFF, 0xF8, 0x2E, 0x00,
0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x9D, 0xFF, 0xDA, 0x0C, 0x44, 0x5D, 0x22, 0xBB, 0xFF, 0x5D, 0xBB,
0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF,
0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0xBB, 0xFF, 0x5D, 0x2E, 0x37, 0x00,
0x1B, 0x4E, 0x44, 0x00, 0x00, 0x15, 0x4E, 0x4A, 0x04, 0x00, 0xBB, 0xFC, 0x6E, 0xFC, 0xFF, 0xFF,
0xCE, 0x57, 0xF8, 0xFF, 0xFF, 0xDF, 0x13, 0xBB, 0xFF, 0xFC, 0x83, 0x8A, 0xFF, 0xFF, 0xFF, 0x90,
0x7D, 0xFC, 0xFF, 0x74, 0xBB, 0xFF, 0xA1, 0x00, 0x00, 0xC7, 0xFF, 0xB0, 0x00, 0x00, 0xAE, 0xFF,
0x9D, 0xBB, 0xFF, 0x5F, 0x00, 0x00, 0xB0, 0xFF, 0x94, 0x00, 0x00, 0xA1, 0xFF, 0xA1, 0xBB, 0xFF,
0x5D, 0x00, 0x00, 0xAE, 0xFF, 0x94, 0x00, 0x00, 0xA1, 0xFF, 0xA1, 0xBB, 0xFF, 0x5D, 0x00, 0x00,
0xAE, 0xFF, 0x94, 0x00, 0x00, 0xA1, 0xFF, 0xA1, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xAE, 0xFF, 0x94,
0x00, 0x00, 0xA1, 0xFF, 0xA1, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0xAE, 0xFF, 0x94, 0x00, 0x00, 0xA1,
0xFF, 0xA1, 0x2E, 0x37, 0x00, 0x17, 0x4E, 0x4A, 0x04, 0x00, 0xBB, 0xFC, 0x6C, 0xFA, 0xFF, 0xFF,
0xE1, 0x1D, 0xBB, 0xFF, 0xFF, 0x8A, 0x74, 0xF2, 0xFF, 0x90, 0xBB, 0xFF, 0xA5, 0x00, 0x00, 0x9D,
0xFF, 0xAE, 0xBB, 0xFF, 0x5F, 0x00, 0x00, 0x6E, 0xFF, 0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A,
0xFF, 0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF, 0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A,
0xFF, 0xAE, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF, 0xAE, 0x00, 0x00, 0x00, 0x35, 0x50, 0x44,
0x02, 0x00, 0x00, 0x00, 0x19, 0xCE, 0xFF, 0xFF, 0xFF, 0xE3, 0x3B, 0x00, 0x00, 0xC7, 0xFF, 0xD4,
0x6C, 0xB4, 0xFF, 0xEE, 0x13, 0x28, 0xFF, 0xFF, 0x22, 0x00, 0x00, 0xDA, 0xFF, 0x68, 0x4E, 0xFF,
0xFA, 0x00, 0x00, 0x00, 0xAA, 0xFF, 0x9B, 0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0xAE, 0xFF, 0x99,
0x11, 0xFC, 0xFF, 0x3D, 0x00, 0x0C, 0xEB, 0xFF, 0x5B, 0x00, 0x99, 0xFF, 0xEE, 0xAA, 0xD8, 0xFF,
0xE3, 0x0C, 0x00, 0x04, 0x8A, 0xFA, 0xFF, 0xFF, 0xC1, 0x22, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0C,
0x06, 0x00, 0x00, 0x00, 0x2E, 0x3B, 0x00, 0x19, 0x4E, 0x39, 0x00, 0x00, 0xBB, 0xFF, 0x70, 0xF4,
0xFF, 0xFF, 0xB0, 0x00, 0xBB, 0xFF, 0xF6, 0x7F, 0x88, 0xFF, 0xFF, 0x63, 0xBB, 0xFF, 0x90, 0x00,
0x00, 0xA3, 0xFF, 0xAA, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x6A, 0xFF, 0xB6, 0xBB, 0xFF, 0x5F, 0x00,
0x00, 0x74, 0xFF, 0xB4, 0xBB, 0xFF, 0xB2, 0x00, 0x00, 0xBD, 0xFF, 0xA3, 0xBB, 0xFF, 0xFF, 0xBF,
0xC3, 0xFF, 0xFF, 0x3B, 0xBB, 0xFF, 0x88, 0xE5, 0xFF, 0xFA, 0x72, 0x00, 0xBB, 0xFF, 0x5B, 0x00,
0x0C, 0x04, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00,
0x00, 0x00, 0x00, 0x00, 0x72, 0x9B, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x4E,
0x44, 0x00, 0x24, 0x3D, 0x13, 0x00, 0x3D, 0xF0, 0xFF, 0xFF, 0xC5, 0xB8, 0xFF, 0x50, 0x00, 0xE1,
0xFF, 0xD6, 0x72, 0xC3, 0xFF, 0xFF, 0x50, 0x33, 0xFF, 0xFF, 0x2A, 0x00, 0x06, 0xF6, 0xFF, 0x50,
0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0xB6, 0xFF, 0x50, 0x4E, 0xFF, 0xFA, 0x00, 0x00, 0x00, 0xB8,
0xFF, 0x50, 0x26, 0xFF, 0xFF, 0x35, 0x00, 0x0A, 0xF6, 0xFF, 0x50, 0x00, 0xCC, 0xFF, 0xE9, 0xA3,
0xD2, 0xFA, 0xFF, 0x50, 0x00, 0x22, 0xD6, 0xFF, 0xFF, 0x8C, 0xE1, 0xFF, 0x50, 0x00, 0x00, 0x00,
0x0A, 0x06, 0x00, 0xF2, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x50, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x9B,
0x30, 0x2E, 0x37, 0x00, 0x0E, 0x4E, 0x22, 0xBB, 0xFA, 0x35, 0xE9, 0xFF, 0x5F, 0xBB, 0xFF, 0xF4,
0xF4, 0xB4, 0x3B, 0xBB, 0xFF, 0xCC, 0x0C, 0x00, 0x00, 0xBB, 0xFF, 0x63, 0x00, 0x00, 0x00, 0xBB,
0xFF, 0x5D, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00,
0x00, 0xBB, 0xFF, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x4E, 0x4E, 0x26, 0x00, 0x00, 0xAC,
0xFF, 0xFF, 0xFF, 0xFF, 0x92, 0x44, 0xFF, 0xF8, 0x55, 0x59, 0xA3, 0x44, 0x41, 0xFF, 0xFF, 0x79,
0x0C, 0x00, 0x00, 0x00, 0xB4, 0xFF, 0xFF, 0xF6, 0x88, 0x08, 0x00, 0x00, 0x4C, 0xC3, 0xFF, 0xFF,
0x9B, 0x04, 0x00, 0x00, 0x00, 0x74, 0xFF, 0xEB, 0x50, 0xD8, 0x9D, 0x7D, 0xC9, 0xFF, 0xB0, 0x37,
0xE9, 0xFF, 0xFF, 0xFF, 0xC1, 0x1B, 0x00, 0x00, 0x0A, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x02, 0xE1,
0x99, 0x00, 0x00, 0x00, 0x50, 0xFF, 0xB8, 0x3D, 0x39, 0x66, 0xFA, 0xFF, 0xFF, 0xFF, 0xF2, 0x41,
0xC1, 0xFF, 0xC5, 0x63, 0x5F, 0x00, 0x9B, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x9B, 0xFF, 0xA1, 0x00,
0x00, 0x00, 0x9B, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x9B, 0xFF, 0xA5, 0x00, 0x00, 0x00, 0x72, 0xFF,
0xFA, 0xA5, 0xB6, 0x00, 0x11, 0xC7, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x00, 0x37,
0x3D, 0x15, 0x00, 0x00, 0x22, 0x3D, 0x28, 0xEB, 0xFF, 0x57, 0x00, 0x00, 0x94, 0xFF, 0xA7, 0xEB,
0xFF, 0x57, 0x00, 0x00, 0x94, 0xFF, 0xA7, 0xEB, 0xFF, 0x57, 0x00, 0x00, 0x94, 0xFF, 0xA7, 0xEB,
0xFF, 0x57, 0x00, 0x00, 0x96, 0xFF, 0xA7, 0xEB, 0xFF, 0x57, 0x00, 0x00, 0xA1, 0xFF, 0xA7, 0xDF,
0xFF, 0x79, 0x00, 0x00, 0xD6, 0xFF, 0xA7, 0x9F, 0xFF, 0xF8, 0xA7, 0xCC, 0xFF, 0xFF, 0xA7, 0x19,
0xCC, 0xFF, 0xFF, 0xD2, 0x4C, 0xFF, 0xA7, 0x00, 0x00, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x3D,
0x3D, 0x13, 0x00, 0x00, 0x00, 0x33, 0x3D, 0x1D, 0xB8, 0xFF, 0x8E, 0x00, 0x00, 0x0A, 0xFA, 0xFF,
0x3D, 0x57, 0xFF, 0xE5, 0x00, 0x00, 0x5D, 0xFF, 0xDF, 0x00, 0x04, 0xEE, 0xFF, 0x3D, 0x00, 0xB2,
0xFF, 0x7D, 0x00, 0x00, 0x90, 0xFF, 0x92, 0x0A, 0xFA, 0xFF, 0x1F, 0x00, 0x00, 0x30, 0xFF, 0xE7,
0x5B, 0xFF, 0xBD, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xFF, 0xBF, 0xFF, 0x5B, 0x00, 0x00, 0x00, 0x00,
0x6E, 0xFF, 0xFF, 0xF2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x11, 0xFA, 0xFF, 0x94, 0x00, 0x00, 0x00,
0x2E, 0x3D, 0x15, 0x00, 0x00, 0x2E, 0x3D, 0x28, 0x00, 0x00, 0x22, 0x3D, 0x28, 0xA7, 0xFF, 0x8A,
0x00, 0x02, 0xF6, 0xFF, 0xD2, 0x00, 0x00, 0xA7, 0xFF, 0x77, 0x57, 0xFF, 0xC9, 0x00, 0x39, 0xFF,
0xE9, 0xFF, 0x0E, 0x00, 0xF2, 0xFF, 0x2E, 0x0E, 0xFC, 0xFC, 0x0C, 0x77, 0xFF, 0x77, 0xFF, 0x50,
0x35, 0xFF, 0xE7, 0x00, 0x00, 0xC5, 0xFF, 0x50, 0xB4, 0xEB, 0x13, 0xFF, 0x8E, 0x77, 0xFF, 0x9D,
0x00, 0x00, 0x7F, 0xFF, 0x85, 0xF4, 0xA7, 0x00, 0xDA, 0xB8, 0xAC, 0xFF, 0x50, 0x00, 0x00, 0x37,
0xFF, 0xB2, 0xFF, 0x6E, 0x00, 0xA3, 0xF2, 0xDF, 0xFA, 0x06, 0x00, 0x00, 0x00, 0xF2, 0xFA, 0xFF,
0x37, 0x00, 0x61, 0xFF, 0xFF, 0xBD, 0x00, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xF8, 0x02, 0x00, 0x30,
0xFF, 0xFF, 0x74, 0x00, 0x00, 0x2C, 0x3D, 0x2E, 0x00, 0x00, 0x02, 0x3D, 0x3D, 0x19, 0x52, 0xFF,
0xFC, 0x2A, 0x00, 0x7B, 0xFF, 0xE9, 0x13, 0x00, 0xAA, 0xFF, 0xC1, 0x1F, 0xF6, 0xFF, 0x52, 0x00,
0x00, 0x15, 0xE9, 0xFF, 0xDF, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xFF, 0xFF, 0xF2, 0x13,
0x00, 0x00, 0x00, 0x00, 0x96, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x41, 0xFF, 0xFA, 0x9D,
0xFF, 0xDF, 0x0C, 0x00, 0x0A, 0xDD, 0xFF, 0x7F, 0x02, 0xD4, 0xFF, 0x94, 0x00, 0x92, 0xFF, 0xDD,
0x06, 0x00, 0x39, 0xFF, 0xFF, 0x3B, 0x3B, 0x3D, 0x17, 0x00, 0x00, 0x00, 0x37, 0x3D, 0x1D, 0xB6,
0xFF, 0xA7, 0x00, 0x00, 0x15, 0xFC, 0xFF, 0x3D, 0x4A, 0xFF, 0xF8, 0x04, 0x00, 0x66, 0xFF, 0xDF,
0x00, 0x02, 0xE3, 0xFF, 0x52, 0x00, 0xBB, 0xFF, 0x7F, 0x00, 0x00, 0x7F, 0xFF, 0xA7, 0x0E, 0xFC,
0xFF, 0x22, 0x00, 0x00, 0x1D, 0xFC, 0xF8, 0x66, 0xFF, 0xC1, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xFF,
0xE3, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x00, 0x4A, 0xFF, 0xFF, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00,
0x02, 0xE3, 0xFF, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE9, 0xFF, 0x3D, 0x00, 0x00, 0x00,
0x1D, 0x46, 0xA7, 0xFF, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x63, 0xFF, 0xFF, 0xEE, 0x35, 0x00, 0x00,
0x00, 0x00, 0x39, 0x9B, 0x72, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x3D, 0x3D, 0x3D, 0x3D,
0x3D, 0x2A, 0x57, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE, 0x33, 0x94, 0x94, 0x94, 0xFA, 0xFF, 0x83,
0x00, 0x00, 0x00, 0x7F, 0xFF, 0xCC, 0x02, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x1F, 0x00, 0x00, 0x13,
0xE7, 0xFF, 0x57, 0x00, 0x00, 0x00, 0xB0, 0xFF, 0x9B, 0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xB6,
0xAE, 0xAE, 0xA1, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x00, 0x00, 0x17, 0x83, 0xA5, 0x35,
0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x4E, 0x00, 0x00, 0xF2, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xF2, 0xFF,
0x00, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x00, 0x00, 0x02, 0x50, 0xFF, 0xF6, 0x00, 0x00, 0xB4, 0xFF,
0xC9, 0x46, 0x00, 0x00, 0x7D, 0xEB, 0xFF, 0x96, 0x00, 0x00, 0x00, 0x11, 0xFA, 0xFF, 0x00, 0x00,
0x00, 0x00, 0xF2, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xFF,
0x7B, 0x19, 0x00, 0x00, 0x88, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x30, 0x52, 0x1B, 0x39, 0x52,
0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2,
0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0xA7, 0xF2, 0x39, 0x52, 0x3D, 0xA5,
0x7F, 0x11, 0x00, 0x00, 0x5B, 0xFF, 0xFF, 0xA1, 0x00, 0x00, 0x00, 0x39, 0xFF, 0xB8, 0x00, 0x00,
0x00, 0x0C, 0xFF, 0xBB, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xC1, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xF8,
0x41, 0x02, 0x00, 0x00, 0x57, 0xD2, 0xFF, 0xA7, 0x00, 0x00, 0xAE, 0xFF, 0xE5, 0x74, 0x00, 0x0C,
0xFF, 0xE9, 0x06, 0x00, 0x00, 0x0C, 0xFF, 0xBB, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xBB, 0x00, 0x00,
0x1D, 0x8E, 0xFF, 0xB6, 0x00, 0x00, 0x5D, 0xFF, 0xFF, 0x72, 0x00, 0x00, 0x1F, 0x50, 0x28, 0x00,
0x00, 0x00, 0x00, 0x46, 0x90, 0x5D, 0x15, 0x00, 0x00, 0x2E, 0x4E, 0xFF, 0xFF, 0xFF, 0xFA, 0xB4,
0xAE, 0xF0, 0x41, 0x52, 0x08, 0x46, 0xA3, 0xEE, 0xE7, 0x79, 0x00, 0x44, 0xBB, 0xD2, 0x88, 0x04,
0x24, 0xFA, 0xC5, 0x9D, 0xFC, 0x83, 0x5B, 0xFF, 0x11, 0x00, 0xAC, 0xB4, 0x3F, 0xFF, 0x7F, 0x4A,
0xE5, 0xA3, 0x00, 0x92, 0xFF, 0xFF, 0xDD, 0x1F, 0x00, 0x00, 0x0C, 0x24, 0x00, 0x00, 0x00, 0x0E,
0x4E, 0x6F, 0x74, 0x6F, 0x20, 0x53, 0x61, 0x6E, 0x73, 0x20, 0x42, 0x6F, 0x6C, 0x64, 0x00, 0x0D,
0x4E, 0x6F, 0x74, 0x6F, 0x53, 0x61, 0x6E, 0x73, 0x2D, 0x42, 0x6F, 0x6C, 0x64, 0x01,
};

2782
jt/NotoSansBold36.h Executable file

File diff suppressed because it is too large Load Diff

2301
jt/Unicode_Test_72.h Executable file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

BIN
jt/data/Final-Frontier-28.vlw Executable file

Binary file not shown.

BIN
jt/data/Latin-Hiragana-24.vlw Executable file

Binary file not shown.

BIN
jt/data/Unicode-Test-72.vlw Executable file

Binary file not shown.

BIN
jt/esptool/4.5.1/boot_app0.bin Executable file

Binary file not shown.

34
jt/esptool/4.5.1/esptool.py Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# This executable script is a thin wrapper around the main functionality
# in the esptool Python package
# When updating this script, please also update espefuse.py and espsecure.py
import contextlib
import os
import sys
if os.name != "nt":
# Linux/macOS: remove current script directory to avoid importing this file
# as a module; we want to import the installed esptool module instead
with contextlib.suppress(ValueError):
if sys.path[0].endswith("/bin"):
sys.path.pop(0)
sys.path.remove(os.path.dirname(sys.executable))
# Linux/macOS: delete imported module entry to force Python to load
# the module from scratch; this enables importing esptool module in
# other Python scripts
with contextlib.suppress(KeyError):
del sys.modules["esptool"]
import esptool
if __name__ == "__main__":
esptool._main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
#
# SPDX-License-Identifier: GPL-2.0-or-later
import esptool
if __name__ == "__main__":
esptool._main()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

1198
jt/esptool/4.5.1/esptool/cmds.py Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
# SPDX-FileCopyrightText: 2014-2023 Espressif Systems (Shanghai) CO LTD,
# other contributors as noted.
#
# SPDX-License-Identifier: GPL-2.0-or-later
import configparser
import os
CONFIG_OPTIONS = [
"timeout",
"chip_erase_timeout",
"max_timeout",
"sync_timeout",
"md5_timeout_per_mb",
"erase_region_timeout_per_mb",
"erase_write_timeout_per_mb",
"mem_end_rom_timeout",
"serial_write_timeout",
"connect_attempts",
"write_block_attempts",
"reset_delay",
"custom_reset_sequence",
]
def _validate_config_file(file_path, verbose=False):
if not os.path.exists(file_path):
return False
cfg = configparser.RawConfigParser()
try:
cfg.read(file_path, encoding="UTF-8")
# Only consider it a valid config file if it contains [esptool] section
if cfg.has_section("esptool"):
if verbose:
unknown_opts = list(set(cfg.options("esptool")) - set(CONFIG_OPTIONS))
unknown_opts.sort()
no_of_unknown_opts = len(unknown_opts)
if no_of_unknown_opts > 0:
suffix = "s" if no_of_unknown_opts > 1 else ""
print(
"Ignoring unknown config file option{}: {}".format(
suffix, ", ".join(unknown_opts)
)
)
return True
except (UnicodeDecodeError, configparser.Error) as e:
if verbose:
print(f"Ignoring invalid config file {file_path}: {e}")
return False
def _find_config_file(dir_path, verbose=False):
for candidate in ("esptool.cfg", "setup.cfg", "tox.ini"):
cfg_path = os.path.join(dir_path, candidate)
if _validate_config_file(cfg_path, verbose):
return cfg_path
return None
def load_config_file(verbose=False):
set_with_env_var = False
env_var_path = os.environ.get("ESPTOOL_CFGFILE")
if env_var_path is not None and _validate_config_file(env_var_path):
cfg_file_path = env_var_path
set_with_env_var = True
else:
home_dir = os.path.expanduser("~")
os_config_dir = (
f"{home_dir}/.config/esptool"
if os.name == "posix"
else f"{home_dir}/AppData/Local/esptool/"
)
# Search priority: 1) current dir, 2) OS specific config dir, 3) home dir
for dir_path in (os.getcwd(), os_config_dir, home_dir):
cfg_file_path = _find_config_file(dir_path, verbose)
if cfg_file_path:
break
cfg = configparser.ConfigParser()
cfg["esptool"] = {} # Create an empty esptool config for when no file is found
if cfg_file_path is not None:
# If config file is found and validated, read and parse it
cfg.read(cfg_file_path)
if verbose:
msg = " (set with ESPTOOL_CFGFILE)" if set_with_env_var else ""
print(
f"Loaded custom configuration from "
f"{os.path.abspath(cfg_file_path)}{msg}"
)
return cfg, cfg_file_path

1608
jt/esptool/4.5.1/esptool/loader.py Executable file

File diff suppressed because it is too large Load Diff

178
jt/esptool/4.5.1/esptool/reset.py Executable file
View File

@ -0,0 +1,178 @@
# SPDX-FileCopyrightText: 2014-2023 Fredrik Ahlberg, Angus Gratton,
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
#
# SPDX-License-Identifier: GPL-2.0-or-later
import os
import struct
import time
from .util import FatalError
# Used for resetting into bootloader on Unix-like systems
if os.name != "nt":
import fcntl
import termios
# Constants used for terminal status lines reading/setting.
# Taken from pySerial's backend for IO:
# https://github.com/pyserial/pyserial/blob/master/serial/serialposix.py
TIOCMSET = getattr(termios, "TIOCMSET", 0x5418)
TIOCMGET = getattr(termios, "TIOCMGET", 0x5415)
TIOCM_DTR = getattr(termios, "TIOCM_DTR", 0x002)
TIOCM_RTS = getattr(termios, "TIOCM_RTS", 0x004)
DEFAULT_RESET_DELAY = 0.05 # default time to wait before releasing boot pin after reset
class ResetStrategy(object):
def __init__(self, port, reset_delay=DEFAULT_RESET_DELAY):
self.port = port
self.reset_delay = reset_delay
def __call__():
pass
def _setDTR(self, state):
self.port.setDTR(state)
def _setRTS(self, state):
self.port.setRTS(state)
# Work-around for adapters on Windows using the usbser.sys driver:
# generate a dummy change to DTR so that the set-control-line-state
# request is sent with the updated RTS state and the same DTR state
self.port.setDTR(self.port.dtr)
def _setDTRandRTS(self, dtr=False, rts=False):
status = struct.unpack(
"I", fcntl.ioctl(self.port.fileno(), TIOCMGET, struct.pack("I", 0))
)[0]
if dtr:
status |= TIOCM_DTR
else:
status &= ~TIOCM_DTR
if rts:
status |= TIOCM_RTS
else:
status &= ~TIOCM_RTS
fcntl.ioctl(self.port.fileno(), TIOCMSET, struct.pack("I", status))
class ClassicReset(ResetStrategy):
"""
Classic reset sequence, sets DTR and RTS lines sequentially.
"""
def __call__(self):
self._setDTR(False) # IO0=HIGH
self._setRTS(True) # EN=LOW, chip in reset
time.sleep(0.1)
self._setDTR(True) # IO0=LOW
self._setRTS(False) # EN=HIGH, chip out of reset
time.sleep(self.reset_delay)
self._setDTR(False) # IO0=HIGH, done
class UnixTightReset(ResetStrategy):
"""
UNIX-only reset sequence with custom implementation,
which allows setting DTR and RTS lines at the same time.
"""
def __call__(self):
self._setDTRandRTS(False, False)
self._setDTRandRTS(True, True)
self._setDTRandRTS(False, True) # IO0=HIGH & EN=LOW, chip in reset
time.sleep(0.1)
self._setDTRandRTS(True, False) # IO0=LOW & EN=HIGH, chip out of reset
time.sleep(self.reset_delay)
self._setDTRandRTS(False, False) # IO0=HIGH, done
self._setDTR(False) # Needed in some environments to ensure IO0=HIGH
class USBJTAGSerialReset(ResetStrategy):
"""
Custom reset sequence, which is required when the device
is connecting via its USB-JTAG-Serial peripheral.
"""
def __call__(self):
self._setRTS(False)
self._setDTR(False) # Idle
time.sleep(0.1)
self._setDTR(True) # Set IO0
self._setRTS(False)
time.sleep(0.1)
self._setRTS(True) # Reset. Calls inverted to go through (1,1) instead of (0,0)
self._setDTR(False)
self._setRTS(True) # RTS set as Windows only propagates DTR on RTS setting
time.sleep(0.1)
self._setDTR(False)
self._setRTS(False) # Chip out of reset
class HardReset(ResetStrategy):
"""
Reset sequence for hard resetting the chip.
Can be used to reset out of the bootloader or to restart a running app.
"""
def __init__(self, port, uses_usb_otg=False):
super().__init__(port)
self.uses_usb_otg = uses_usb_otg
def __call__(self):
self._setRTS(True) # EN->LOW
if self.uses_usb_otg:
# Give the chip some time to come out of reset,
# to be able to handle further DTR/RTS transitions
time.sleep(0.2)
self._setRTS(False)
time.sleep(0.2)
else:
time.sleep(0.1)
self._setRTS(False)
class CustomReset(ResetStrategy):
"""
Custom reset strategy defined with a string.
CustomReset object is created as "rst = CustomReset(port, seq_str)"
and can be later executed simply with "rst()"
The seq_str input string consists of individual commands divided by "|".
Commands (e.g. R0) are defined by a code (R) and an argument (0).
The commands are:
D: setDTR - 1=True / 0=False
R: setRTS - 1=True / 0=False
U: setDTRandRTS (Unix-only) - 0,0 / 0,1 / 1,0 / or 1,1
W: Wait (time delay) - positive float number
e.g.
"D0|R1|W0.1|D1|R0|W0.05|D0" represents the ClassicReset strategy
"U1,1|U0,1|W0.1|U1,0|W0.05|U0,0" represents the UnixTightReset strategy
"""
format_dict = {
"D": "self.port.setDTR({})",
"R": "self.port.setRTS({})",
"W": "time.sleep({})",
"U": "self._setDTRandRTS({})",
}
def __call__(self):
exec(self.constructed_strategy)
def __init__(self, port, seq_str):
super().__init__(port)
self.constructed_strategy = self._parse_string_to_seq(seq_str)
def _parse_string_to_seq(self, seq_str):
try:
cmds = seq_str.split("|")
fn_calls_list = [self.format_dict[cmd[0]].format(cmd[1:]) for cmd in cmds]
except Exception as e:
raise FatalError(f'Invalid "custom_reset_sequence" option format: {e}')
return "\n".join(fn_calls_list)

View File

@ -0,0 +1,31 @@
from .esp32 import ESP32ROM
from .esp32c2 import ESP32C2ROM
from .esp32c3 import ESP32C3ROM
from .esp32c6 import ESP32C6ROM
from .esp32c6beta import ESP32C6BETAROM
from .esp32h2 import ESP32H2ROM
from .esp32h2beta1 import ESP32H2BETA1ROM
from .esp32h2beta2 import ESP32H2BETA2ROM
from .esp32s2 import ESP32S2ROM
from .esp32s3 import ESP32S3ROM
from .esp32s3beta2 import ESP32S3BETA2ROM
from .esp8266 import ESP8266ROM
CHIP_DEFS = {
"esp8266": ESP8266ROM,
"esp32": ESP32ROM,
"esp32s2": ESP32S2ROM,
"esp32s3beta2": ESP32S3BETA2ROM,
"esp32s3": ESP32S3ROM,
"esp32c3": ESP32C3ROM,
"esp32c6beta": ESP32C6BETAROM,
"esp32h2beta1": ESP32H2BETA1ROM,
"esp32h2beta2": ESP32H2BETA2ROM,
"esp32c2": ESP32C2ROM,
"esp32c6": ESP32C6ROM,
"esp32h2": ESP32H2ROM,
}
CHIP_LIST = list(CHIP_DEFS.keys())
ROM_LIST = list(CHIP_DEFS.values())

Some files were not shown because too many files have changed in this diff Show More