diff --git a/FloridOS/Fflorid.iso b/FloridOS/Fflorid.iso new file mode 100644 index 0000000..821f479 Binary files /dev/null and b/FloridOS/Fflorid.iso differ diff --git a/FloridOS/Makefile b/FloridOS/Makefile new file mode 100644 index 0000000..ee4c66a --- /dev/null +++ b/FloridOS/Makefile @@ -0,0 +1,40 @@ +CC = gcc +LD = ld +CFLAGS = -Wall -Wextra -std=c11 -ffreestanding -fno-stack-protector -fno-stack-check -fno-lto -fPIE -m64 -march=x86-64 -Isrc +LDFLAGS = -T linker.ld -static -nostdlib -no-pie -z max-page-size=0x1000 + +# Explicitly define the objects +OBJS = build/kernel.o build/drivers/tty.o build/drivers/keyboard.o + +all: Fflorid.iso + +# Rule to make the build directories +build_dirs: + mkdir -p build/drivers build/shell + +# Rule to compile C files +build/%.o: src/%.c | build_dirs + $(CC) $(CFLAGS) -c $< -o $@ + +# THE MISSING RULE: Link the kernel +build/kernel.bin: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o build/kernel.bin + +# Build the ISO +Fflorid.iso: build/kernel.bin + rm -rf iso_root + mkdir -p iso_root + cp build/kernel.bin iso_root/kernel + cp limine.cfg iso_root/limine.cfg + cp limine/limine-bios.sys iso_root/limine-bios.sys + cp limine/limine-bios-cd.bin iso_root/limine-bios-cd.bin + xorriso -as mkisofs -b limine-bios-cd.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + iso_root -o Fflorid.iso + ./limine/limine bios-install Fflorid.iso + +run: Fflorid.iso + qemu-system-x86_64 -cdrom Fflorid.iso + +clean: + rm -rf build iso_root Fflorid.iso \ No newline at end of file diff --git a/FloridOS/build/drivers/keyboard.o b/FloridOS/build/drivers/keyboard.o new file mode 100644 index 0000000..4a8b6bd Binary files /dev/null and b/FloridOS/build/drivers/keyboard.o differ diff --git a/FloridOS/build/drivers/tty.o b/FloridOS/build/drivers/tty.o new file mode 100644 index 0000000..6b68565 Binary files /dev/null and b/FloridOS/build/drivers/tty.o differ diff --git a/FloridOS/build/kernel.bin b/FloridOS/build/kernel.bin new file mode 100644 index 0000000..cf66317 Binary files /dev/null and b/FloridOS/build/kernel.bin differ diff --git a/FloridOS/build/kernel.o b/FloridOS/build/kernel.o new file mode 100644 index 0000000..f5dcd0e Binary files /dev/null and b/FloridOS/build/kernel.o differ diff --git a/FloridOS/iso_root/kernel b/FloridOS/iso_root/kernel new file mode 100644 index 0000000..cf66317 Binary files /dev/null and b/FloridOS/iso_root/kernel differ diff --git a/FloridOS/iso_root/limine-bios-cd.bin b/FloridOS/iso_root/limine-bios-cd.bin new file mode 100644 index 0000000..0621f1e Binary files /dev/null and b/FloridOS/iso_root/limine-bios-cd.bin differ diff --git a/FloridOS/iso_root/limine-bios.sys b/FloridOS/iso_root/limine-bios.sys new file mode 100644 index 0000000..067c730 Binary files /dev/null and b/FloridOS/iso_root/limine-bios.sys differ diff --git a/FloridOS/iso_root/limine.cfg b/FloridOS/iso_root/limine.cfg new file mode 100644 index 0000000..f07f099 --- /dev/null +++ b/FloridOS/iso_root/limine.cfg @@ -0,0 +1,5 @@ +TIMEOUT=3 + +:Florid OS + PROTOCOL=limine + KERNEL_PATH=boot:///kernel diff --git a/FloridOS/limine.cfg b/FloridOS/limine.cfg new file mode 100644 index 0000000..f07f099 --- /dev/null +++ b/FloridOS/limine.cfg @@ -0,0 +1,5 @@ +TIMEOUT=3 + +:Florid OS + PROTOCOL=limine + KERNEL_PATH=boot:///kernel diff --git a/FloridOS/limine/BOOTAA64.EFI b/FloridOS/limine/BOOTAA64.EFI new file mode 100644 index 0000000..78bd960 Binary files /dev/null and b/FloridOS/limine/BOOTAA64.EFI differ diff --git a/FloridOS/limine/BOOTIA32.EFI b/FloridOS/limine/BOOTIA32.EFI new file mode 100644 index 0000000..9c4d6a2 Binary files /dev/null and b/FloridOS/limine/BOOTIA32.EFI differ diff --git a/FloridOS/limine/BOOTRISCV64.EFI b/FloridOS/limine/BOOTRISCV64.EFI new file mode 100644 index 0000000..e54f159 Binary files /dev/null and b/FloridOS/limine/BOOTRISCV64.EFI differ diff --git a/FloridOS/limine/BOOTX64.EFI b/FloridOS/limine/BOOTX64.EFI new file mode 100644 index 0000000..e118efb Binary files /dev/null and b/FloridOS/limine/BOOTX64.EFI differ diff --git a/FloridOS/limine/LICENSE b/FloridOS/limine/LICENSE new file mode 100644 index 0000000..fad56e1 --- /dev/null +++ b/FloridOS/limine/LICENSE @@ -0,0 +1,22 @@ +Copyright (C) 2019-2024 mintsuki and contributors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/FloridOS/limine/Makefile b/FloridOS/limine/Makefile new file mode 100644 index 0000000..5544143 --- /dev/null +++ b/FloridOS/limine/Makefile @@ -0,0 +1,38 @@ +CC ?= cc +STRIP ?= strip +INSTALL ?= ./install-sh + +PREFIX ?= /usr/local + +CFLAGS ?= -g -O2 -pipe + +.PHONY: all +all: limine + +.PHONY: install +install: all + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/share' + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/share/limine' + $(INSTALL) -m 644 limine-bios.sys '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 limine-bios-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 limine-uefi-cd.bin '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 limine-bios-pxe.bin '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTX64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTIA32.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTAA64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -m 644 BOOTRISCV64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/include' + $(INSTALL) -m 644 limine.h '$(DESTDIR)$(PREFIX)/include/' + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' + $(INSTALL) limine '$(DESTDIR)$(PREFIX)/bin/' + +.PHONY: install-strip +install-strip: install + $(STRIP) '$(DESTDIR)$(PREFIX)/bin/limine' + +.PHONY: clean +clean: + rm -f limine limine.exe + +limine: limine.c + $(CC) $(CFLAGS) -Wall -Wextra $(WERROR_FLAG) $(CPPFLAGS) $(LDFLAGS) -std=c99 limine.c $(LIBS) -o $@ diff --git a/FloridOS/limine/install-sh b/FloridOS/limine/install-sh new file mode 100644 index 0000000..7c56c9c --- /dev/null +++ b/FloridOS/limine/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2023-11-23.18; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Report bugs to . +GNU Automake home page: . +General help using GNU software: ." + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/FloridOS/limine/limine b/FloridOS/limine/limine new file mode 100644 index 0000000..1964b48 Binary files /dev/null and b/FloridOS/limine/limine differ diff --git a/FloridOS/limine/limine-bios-cd.bin b/FloridOS/limine/limine-bios-cd.bin new file mode 100644 index 0000000..0621f1e Binary files /dev/null and b/FloridOS/limine/limine-bios-cd.bin differ diff --git a/FloridOS/limine/limine-bios-hdd.h b/FloridOS/limine/limine-bios-hdd.h new file mode 100644 index 0000000..d93b38f --- /dev/null +++ b/FloridOS/limine/limine-bios-hdd.h @@ -0,0 +1,1341 @@ +const uint8_t binary_limine_hdd_bin_data[] = { + 0xeb, 0x3c, 0x90, 0x4c, 0x49, 0x4d, 0x49, 0x4e, 0x45, 0x20, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x49, 0x4d, 0x49, 0x4e, + 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xfc, + 0xea, 0x45, 0x7c, 0x00, 0x00, 0x31, 0xf6, 0x8e, 0xde, 0x8e, 0xc6, 0x8e, 0xd6, 0xbc, 0x00, 0x7c, + 0xfb, 0x80, 0xfa, 0x80, 0x0f, 0x82, 0x10, 0x01, 0x80, 0xfa, 0x8f, 0x0f, 0x87, 0x08, 0x01, 0xb4, + 0x41, 0xbb, 0xaa, 0x55, 0xcd, 0x13, 0x0f, 0x82, 0xfc, 0x00, 0x81, 0xfb, 0x55, 0xaa, 0x0f, 0x85, + 0xf3, 0x00, 0x68, 0x00, 0x70, 0x07, 0xbf, 0xa8, 0x7d, 0x66, 0x8b, 0x05, 0x66, 0x8b, 0x6d, 0x04, + 0x31, 0xdb, 0x66, 0x31, 0xc9, 0x8b, 0x4d, 0xfc, 0xe8, 0x55, 0x00, 0x0f, 0x82, 0xd5, 0x00, 0x66, + 0x8b, 0x45, 0x08, 0x66, 0x8b, 0x6d, 0x0c, 0x01, 0xcb, 0x8b, 0x4d, 0xfe, 0xe8, 0x41, 0x00, 0x0f, + 0x82, 0xc0, 0x00, 0x0f, 0x01, 0x16, 0x4d, 0x7d, 0xfa, 0x0f, 0x20, 0xc0, 0x0f, 0xba, 0xe8, 0x00, + 0x0f, 0x22, 0xc0, 0xea, 0x79, 0x7d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xbe, 0x00, 0x80, 0xc7, 0x04, 0x10, 0x00, 0xc7, 0x44, 0x02, 0x01, 0x00, 0x89, 0x5c, 0x04, + 0x8c, 0x44, 0x06, 0x52, 0x56, 0x66, 0x50, 0x66, 0x55, 0xb4, 0x48, 0xbe, 0x10, 0x80, 0xc7, 0x04, + 0x1e, 0x00, 0xcd, 0x13, 0x72, 0x45, 0x8b, 0x6c, 0x18, 0x89, 0xc8, 0x66, 0xc1, 0xe9, 0x10, 0x89, + 0xca, 0x31, 0xc9, 0xf7, 0xf5, 0x85, 0xd2, 0x0f, 0x95, 0xc1, 0x01, 0xc1, 0x66, 0x5a, 0x66, 0x58, + 0x5e, 0x66, 0xf7, 0xf5, 0x66, 0x89, 0x44, 0x08, 0x66, 0xc7, 0x44, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x5a, 0xb4, 0x42, 0xf8, 0xcd, 0x13, 0x72, 0x13, 0x01, 0x6c, 0x04, 0x66, 0x31, 0xdb, 0x66, 0xff, + 0x44, 0x08, 0x0f, 0x90, 0xc3, 0x66, 0x01, 0x5c, 0x0c, 0xe2, 0xe6, 0x61, 0xc3, 0x17, 0x00, 0x4b, + 0x7d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x93, 0xcf, 0x00, 0x46, 0x46, 0x46, 0x46, 0x46, 0x81, 0xc6, 0x30, 0x4f, 0x68, 0x00, 0xb8, 0x07, + 0x26, 0x89, 0x36, 0x00, 0x00, 0xfb, 0xf4, 0xeb, 0xfd, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x8e, 0xd8, + 0x8e, 0xc0, 0x8e, 0xe0, 0x8e, 0xe8, 0x8e, 0xd0, 0x81, 0xe2, 0xff, 0x00, 0x00, 0x00, 0x6a, 0x00, + 0x52, 0x68, 0x08, 0x47, 0x00, 0x00, 0x68, 0xa0, 0x0a, 0x07, 0x00, 0xe8, 0x60, 0x82, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, + 0xfc, 0x30, 0xc0, 0xbf, 0x91, 0x0a, 0x07, 0x00, 0xb9, 0x91, 0x0a, 0x07, 0x00, 0x81, 0xe9, 0x91, + 0x0a, 0x07, 0x00, 0xf3, 0xaa, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x57, 0x56, 0x0f, 0xb6, 0x74, 0x24, + 0x14, 0x8b, 0x7c, 0x24, 0x18, 0xff, 0x74, 0x24, 0x10, 0xff, 0x74, 0x24, 0x10, 0x68, 0x00, 0xf0, + 0x00, 0x00, 0xe8, 0x14, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c, 0xbc, 0x00, 0xf0, 0x00, 0x00, 0x31, + 0xed, 0x57, 0x56, 0x6a, 0x00, 0x68, 0x00, 0xf0, 0x00, 0x00, 0xc3, 0x55, 0x53, 0x57, 0x56, 0x8b, + 0x54, 0x24, 0x1c, 0xb8, 0xfd, 0xff, 0xff, 0xff, 0x83, 0xfa, 0x12, 0x0f, 0x82, 0xa2, 0x00, 0x00, + 0x00, 0x8b, 0x4c, 0x24, 0x18, 0x80, 0x39, 0x1f, 0x0f, 0x85, 0x95, 0x00, 0x00, 0x00, 0x80, 0x79, + 0x01, 0x8b, 0x0f, 0x85, 0x8b, 0x00, 0x00, 0x00, 0x80, 0x79, 0x02, 0x08, 0x0f, 0x85, 0x81, 0x00, + 0x00, 0x00, 0x0f, 0xb6, 0x59, 0x03, 0x83, 0xfb, 0x1f, 0x77, 0x78, 0x8d, 0x71, 0x0a, 0xf6, 0xc3, + 0x04, 0x74, 0x0e, 0x0f, 0xb7, 0x3e, 0x8d, 0x6a, 0xf4, 0x39, 0xfd, 0x72, 0x66, 0x8d, 0x74, 0x3e, + 0x02, 0xf6, 0xc3, 0x08, 0x75, 0x04, 0x89, 0xf7, 0xeb, 0x13, 0x89, 0xf5, 0x29, 0xcd, 0x39, 0xd5, + 0x73, 0x51, 0x8d, 0x7e, 0x01, 0x45, 0x80, 0x3e, 0x00, 0x89, 0xfe, 0x75, 0xf1, 0x80, 0xfb, 0x10, + 0x73, 0x04, 0x89, 0xfd, 0xeb, 0x13, 0x89, 0xfe, 0x29, 0xce, 0x39, 0xd6, 0x73, 0x35, 0x8d, 0x6f, + 0x01, 0x46, 0x80, 0x3f, 0x00, 0x89, 0xef, 0x75, 0xf1, 0x83, 0xe3, 0x02, 0x01, 0xeb, 0x01, 0xd1, + 0x29, 0xd9, 0x83, 0xf9, 0x08, 0x7c, 0x1c, 0x83, 0xc1, 0xf8, 0x51, 0x53, 0xff, 0x74, 0x24, 0x1c, + 0xe8, 0x13, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c, 0x31, 0xc9, 0x85, 0xc0, 0x0f, 0x94, 0xc1, 0x8d, + 0x44, 0x49, 0xfd, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x53, 0x57, 0x56, 0x81, 0xec, 0x44, 0x06, + 0x00, 0x00, 0x8b, 0x84, 0x24, 0x58, 0x06, 0x00, 0x00, 0x8b, 0x8c, 0x24, 0x5c, 0x06, 0x00, 0x00, + 0x8d, 0x54, 0x24, 0x3c, 0x89, 0x4a, 0xe4, 0x03, 0x8c, 0x24, 0x60, 0x06, 0x00, 0x00, 0x89, 0x4a, + 0xe8, 0x31, 0xc9, 0x89, 0x4a, 0xec, 0x89, 0x4a, 0xf0, 0x89, 0x4a, 0xf4, 0x89, 0x42, 0xfc, 0x89, + 0x42, 0xf8, 0x8b, 0x54, 0x24, 0x2c, 0x85, 0xd2, 0x7e, 0x0a, 0x8b, 0x44, 0x24, 0x28, 0x89, 0x44, + 0x24, 0x0c, 0xeb, 0x4c, 0x8b, 0x74, 0x24, 0x20, 0x8b, 0x44, 0x24, 0x24, 0x8b, 0x4c, 0x24, 0x28, + 0x89, 0x4c, 0x24, 0x0c, 0x89, 0xd1, 0x39, 0xc6, 0x74, 0x1e, 0x8d, 0x56, 0x01, 0x89, 0x54, 0x24, + 0x20, 0x0f, 0xb6, 0x36, 0xd3, 0xe6, 0x8b, 0x7c, 0x24, 0x0c, 0x09, 0xf7, 0x89, 0x7c, 0x24, 0x0c, + 0x89, 0x7c, 0x24, 0x28, 0x89, 0xd6, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, + 0x89, 0xc6, 0x8d, 0x51, 0x08, 0x89, 0x54, 0x24, 0x2c, 0x83, 0xf9, 0xf9, 0x89, 0xd1, 0x7c, 0xc6, + 0x8b, 0x74, 0x24, 0x0c, 0xd1, 0xee, 0x89, 0x74, 0x24, 0x28, 0x8d, 0x5a, 0xff, 0x89, 0x5c, 0x24, + 0x2c, 0x83, 0xfb, 0x01, 0x77, 0x45, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x7c, 0x24, 0x24, 0x83, 0xc2, + 0xf7, 0x8d, 0x5a, 0x08, 0x39, 0xf9, 0x74, 0x18, 0x8d, 0x41, 0x01, 0x89, 0x44, 0x24, 0x20, 0x0f, + 0xb6, 0x29, 0x89, 0xd9, 0xd3, 0xe5, 0x09, 0xee, 0x89, 0x74, 0x24, 0x28, 0x89, 0xc1, 0xeb, 0x0a, + 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xf9, 0x83, 0xc2, 0x10, 0x89, 0x54, 0x24, + 0x2c, 0x83, 0xfb, 0xfa, 0x89, 0xda, 0x7c, 0xc9, 0x83, 0xc3, 0x08, 0x89, 0xf1, 0xc1, 0xe9, 0x02, + 0x89, 0x4c, 0x24, 0x04, 0x89, 0x4c, 0x24, 0x28, 0x8d, 0x53, 0xfe, 0x89, 0x54, 0x24, 0x2c, 0xb8, + 0xfd, 0xff, 0xff, 0xff, 0x83, 0xe6, 0x03, 0x0f, 0x84, 0x7a, 0x04, 0x00, 0x00, 0x83, 0xfe, 0x02, + 0x0f, 0x84, 0xe6, 0x00, 0x00, 0x00, 0x83, 0xfe, 0x01, 0x8d, 0xb4, 0x24, 0xa0, 0x02, 0x00, 0x00, + 0x0f, 0x85, 0xdf, 0x04, 0x00, 0x00, 0xb8, 0xe0, 0xff, 0xff, 0xff, 0x66, 0xc7, 0x44, 0x04, 0x5c, + 0x00, 0x00, 0x83, 0xc0, 0x02, 0x75, 0xf4, 0xc7, 0x44, 0x24, 0x4a, 0x18, 0x00, 0x98, 0x00, 0x66, + 0xc7, 0x44, 0x24, 0x4e, 0x70, 0x00, 0xb8, 0xe8, 0xff, 0xff, 0xff, 0x8d, 0x88, 0x18, 0x01, 0x00, + 0x00, 0x66, 0x89, 0x8c, 0x44, 0x8c, 0x00, 0x00, 0x00, 0x40, 0x75, 0xef, 0x31, 0xc0, 0x66, 0x89, + 0x84, 0x44, 0x8c, 0x00, 0x00, 0x00, 0x40, 0x3d, 0x90, 0x00, 0x00, 0x00, 0x75, 0xf0, 0xb8, 0xf8, + 0xff, 0xff, 0xff, 0x8d, 0x88, 0x20, 0x01, 0x00, 0x00, 0x66, 0x89, 0x8c, 0x44, 0xbc, 0x01, 0x00, + 0x00, 0x40, 0x75, 0xef, 0xb8, 0x90, 0xff, 0xff, 0xff, 0x8d, 0x88, 0x00, 0x01, 0x00, 0x00, 0x66, + 0x89, 0x8c, 0x44, 0x9c, 0x02, 0x00, 0x00, 0x40, 0x75, 0xef, 0xc7, 0x84, 0x24, 0x9c, 0x02, 0x00, + 0x00, 0x1d, 0x01, 0x00, 0x00, 0xb8, 0xe0, 0xff, 0xff, 0xff, 0x66, 0xc7, 0x84, 0x04, 0xc0, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x83, 0xc0, 0x02, 0x75, 0xf1, 0x66, 0xc7, 0x84, 0x24, 0xaa, 0x02, 0x00, + 0x00, 0x20, 0x00, 0x31, 0xc0, 0x66, 0x89, 0x84, 0x44, 0xc0, 0x02, 0x00, 0x00, 0x40, 0x83, 0xf8, + 0x20, 0x75, 0xf2, 0xc7, 0x84, 0x24, 0x00, 0x05, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x8d, 0x4c, + 0x24, 0x20, 0x8d, 0x54, 0x24, 0x3c, 0x56, 0xe8, 0x7d, 0x04, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, + 0xc0, 0x0f, 0x84, 0xe1, 0x03, 0x00, 0x00, 0xe9, 0x09, 0x04, 0x00, 0x00, 0x83, 0xfa, 0x04, 0x77, + 0x4d, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x74, 0x24, 0x24, 0x83, 0xc3, 0xf6, 0x8d, 0x53, 0x08, 0x39, + 0xf1, 0x74, 0x20, 0x8d, 0x79, 0x01, 0x89, 0x7c, 0x24, 0x20, 0x0f, 0xb6, 0x01, 0x89, 0xd1, 0xd3, + 0xe0, 0x8b, 0x4c, 0x24, 0x04, 0x09, 0xc1, 0x89, 0x4c, 0x24, 0x04, 0x89, 0x4c, 0x24, 0x28, 0x89, + 0xf9, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xf1, 0x83, 0xc3, 0x10, + 0x89, 0x5c, 0x24, 0x2c, 0x83, 0xfa, 0xfd, 0x89, 0xd3, 0x7c, 0xc1, 0x83, 0xc2, 0x08, 0x8b, 0x74, + 0x24, 0x04, 0x89, 0xf3, 0xc1, 0xeb, 0x05, 0x89, 0x5c, 0x24, 0x28, 0x8d, 0x42, 0xfb, 0x89, 0x44, + 0x24, 0x2c, 0x83, 0xf8, 0x04, 0x77, 0x4d, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x74, 0x24, 0x24, 0x83, + 0xc2, 0xf3, 0x8d, 0x42, 0x08, 0x39, 0xf1, 0x74, 0x1c, 0x8d, 0x79, 0x01, 0x89, 0x7c, 0x24, 0x20, + 0x89, 0xdd, 0x0f, 0xb6, 0x19, 0x89, 0xc1, 0xd3, 0xe3, 0x09, 0xdd, 0x89, 0xeb, 0x89, 0x6c, 0x24, + 0x28, 0x89, 0xf9, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xf1, 0x83, + 0xc2, 0x10, 0x89, 0x54, 0x24, 0x2c, 0x83, 0xf8, 0xfd, 0x89, 0xc2, 0x7c, 0xc5, 0x83, 0xc0, 0x08, + 0x8b, 0x74, 0x24, 0x04, 0x89, 0xd9, 0xc1, 0xe9, 0x05, 0x89, 0x0c, 0x24, 0x89, 0x4c, 0x24, 0x28, + 0x8d, 0x48, 0xfb, 0x89, 0x4c, 0x24, 0x2c, 0x83, 0xf9, 0x03, 0x77, 0x4d, 0x8b, 0x7c, 0x24, 0x20, + 0x8b, 0x74, 0x24, 0x24, 0x83, 0xc0, 0xf3, 0x8d, 0x48, 0x08, 0x39, 0xf7, 0x74, 0x1c, 0x8d, 0x57, + 0x01, 0x89, 0x54, 0x24, 0x20, 0x0f, 0xb6, 0x3f, 0xd3, 0xe7, 0x8b, 0x2c, 0x24, 0x09, 0xfd, 0x89, + 0x2c, 0x24, 0x89, 0x6c, 0x24, 0x28, 0x89, 0xd7, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, + 0x00, 0x00, 0x89, 0xf7, 0x83, 0xc0, 0x10, 0x89, 0x44, 0x24, 0x2c, 0x83, 0xf9, 0xfc, 0x89, 0xc8, + 0x7c, 0xc5, 0x83, 0xc1, 0x08, 0x8b, 0x74, 0x24, 0x04, 0x83, 0xe6, 0x1f, 0x8b, 0x04, 0x24, 0xc1, + 0xe8, 0x04, 0x89, 0x44, 0x24, 0x28, 0x83, 0xc1, 0xfc, 0x89, 0x4c, 0x24, 0x2c, 0x83, 0xfe, 0x1d, + 0x0f, 0x87, 0xc3, 0x02, 0x00, 0x00, 0x83, 0xe3, 0x1f, 0x83, 0xfb, 0x1d, 0x0f, 0x87, 0xb7, 0x02, + 0x00, 0x00, 0xc7, 0x44, 0x24, 0x08, 0xfd, 0xff, 0xff, 0xff, 0x81, 0xc6, 0x01, 0x01, 0x00, 0x00, + 0x89, 0x74, 0x24, 0x04, 0x43, 0x89, 0x5c, 0x24, 0x10, 0x83, 0x24, 0x24, 0x0f, 0xba, 0xed, 0xff, + 0xff, 0xff, 0xc6, 0x84, 0x14, 0x17, 0x05, 0x00, 0x00, 0x00, 0x42, 0x75, 0xf5, 0x83, 0x04, 0x24, + 0x03, 0x8b, 0x54, 0x24, 0x20, 0x8b, 0x74, 0x24, 0x24, 0x31, 0xdb, 0x83, 0xf9, 0x02, 0x7f, 0x36, + 0x89, 0xd7, 0x39, 0xf7, 0x74, 0x16, 0x8d, 0x57, 0x01, 0x89, 0x54, 0x24, 0x20, 0x0f, 0xb6, 0x3f, + 0xd3, 0xe7, 0x09, 0xf8, 0x89, 0x44, 0x24, 0x28, 0x89, 0xd7, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, + 0x01, 0x00, 0x00, 0x00, 0x89, 0xf7, 0x8d, 0x69, 0x08, 0x89, 0x6c, 0x24, 0x2c, 0x83, 0xf9, 0xfb, + 0x89, 0xe9, 0x7c, 0xce, 0xeb, 0x02, 0x89, 0xcd, 0x89, 0xc1, 0xc1, 0xe9, 0x03, 0x89, 0x4c, 0x24, + 0x28, 0x83, 0xc5, 0xfd, 0x89, 0x6c, 0x24, 0x2c, 0x24, 0x07, 0x0f, 0xb6, 0xbb, 0x7e, 0x0a, 0x07, + 0x00, 0x88, 0x84, 0x3c, 0x04, 0x05, 0x00, 0x00, 0x3b, 0x1c, 0x24, 0x8d, 0x5b, 0x01, 0x89, 0xc8, + 0x89, 0xe9, 0x75, 0x97, 0x8d, 0x4c, 0x24, 0x3c, 0x8d, 0x94, 0x24, 0x04, 0x05, 0x00, 0x00, 0x6a, + 0x13, 0xe8, 0xf8, 0x03, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, 0xc0, 0x0f, 0x85, 0xf2, 0x01, 0x00, + 0x00, 0x83, 0xbc, 0x24, 0x9c, 0x02, 0x00, 0x00, 0xff, 0x0f, 0x84, 0xf2, 0x01, 0x00, 0x00, 0x8b, + 0x44, 0x24, 0x04, 0x8b, 0x7c, 0x24, 0x10, 0x8d, 0x1c, 0x07, 0x31, 0xf6, 0x89, 0x5c, 0x24, 0x14, + 0x8d, 0x4c, 0x24, 0x20, 0x8d, 0x54, 0x24, 0x3c, 0xe8, 0x6e, 0x03, 0x00, 0x00, 0x3b, 0x84, 0x24, + 0x9c, 0x02, 0x00, 0x00, 0x0f, 0x8f, 0xc7, 0x01, 0x00, 0x00, 0x66, 0x83, 0xf8, 0x12, 0x74, 0x38, + 0x0f, 0xb7, 0xc8, 0xba, 0x03, 0x00, 0x00, 0x00, 0x83, 0xf9, 0x11, 0x74, 0x24, 0x83, 0xf9, 0x10, + 0x0f, 0x85, 0xc0, 0x00, 0x00, 0x00, 0x85, 0xf6, 0x0f, 0x84, 0xa3, 0x01, 0x00, 0x00, 0x8d, 0x84, + 0x24, 0x04, 0x05, 0x00, 0x00, 0x0f, 0xb6, 0x44, 0x06, 0xff, 0xb9, 0x02, 0x00, 0x00, 0x00, 0xeb, + 0x13, 0xb9, 0x03, 0x00, 0x00, 0x00, 0xeb, 0x0a, 0xba, 0x0b, 0x00, 0x00, 0x00, 0xb9, 0x07, 0x00, + 0x00, 0x00, 0x31, 0xc0, 0x89, 0x44, 0x24, 0x1c, 0x8b, 0x5c, 0x24, 0x2c, 0x89, 0x0c, 0x24, 0x39, + 0xcb, 0x89, 0x54, 0x24, 0x18, 0x7d, 0x46, 0x8b, 0x6c, 0x24, 0x20, 0x8b, 0x44, 0x24, 0x24, 0x8b, + 0x7c, 0x24, 0x28, 0x8b, 0x0c, 0x24, 0x39, 0xc5, 0x74, 0x1c, 0x8d, 0x55, 0x01, 0x89, 0x54, 0x24, + 0x20, 0x0f, 0xb6, 0x6d, 0x00, 0x89, 0xd9, 0xd3, 0xe5, 0x09, 0xef, 0x89, 0x7c, 0x24, 0x28, 0x89, + 0xd5, 0x8b, 0x0c, 0x24, 0xeb, 0x0a, 0xc7, 0x44, 0x24, 0x30, 0x01, 0x00, 0x00, 0x00, 0x89, 0xc5, + 0x83, 0xc3, 0x08, 0x89, 0x5c, 0x24, 0x2c, 0x39, 0xcb, 0x7c, 0xcb, 0xeb, 0x07, 0x8b, 0x7c, 0x24, + 0x28, 0x8b, 0x0c, 0x24, 0x31, 0xed, 0x4d, 0xd3, 0xe5, 0xf7, 0xd5, 0x21, 0xfd, 0x03, 0x6c, 0x24, + 0x18, 0xd3, 0xef, 0x89, 0x7c, 0x24, 0x28, 0x29, 0xcb, 0x89, 0x5c, 0x24, 0x2c, 0x8b, 0x5c, 0x24, + 0x14, 0x89, 0xd8, 0x29, 0xf0, 0x39, 0xc5, 0x8b, 0x7c, 0x24, 0x10, 0x8b, 0x44, 0x24, 0x1c, 0x76, + 0x12, 0xe9, 0xeb, 0x00, 0x00, 0x00, 0x39, 0xf3, 0xbd, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x84, 0xde, + 0x00, 0x00, 0x00, 0x88, 0x84, 0x34, 0x04, 0x05, 0x00, 0x00, 0x46, 0x4d, 0x75, 0xf5, 0x39, 0xde, + 0x0f, 0x82, 0xea, 0xfe, 0xff, 0xff, 0x80, 0xbc, 0x24, 0x04, 0x06, 0x00, 0x00, 0x00, 0x0f, 0x84, + 0xbd, 0x00, 0x00, 0x00, 0x8d, 0x4c, 0x24, 0x3c, 0x8d, 0x94, 0x24, 0x04, 0x05, 0x00, 0x00, 0x8b, + 0x74, 0x24, 0x04, 0x56, 0xe8, 0x95, 0x02, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, 0xc0, 0x0f, 0x85, + 0x8f, 0x00, 0x00, 0x00, 0x8d, 0x94, 0x34, 0x04, 0x05, 0x00, 0x00, 0x8d, 0xb4, 0x24, 0xa0, 0x02, + 0x00, 0x00, 0x89, 0xf1, 0x57, 0xe8, 0x74, 0x02, 0x00, 0x00, 0x83, 0xc4, 0x04, 0x85, 0xc0, 0x0f, + 0x84, 0x59, 0xfc, 0xff, 0xff, 0xeb, 0x7e, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x54, 0x24, 0x24, 0x29, + 0xca, 0x83, 0xfa, 0x04, 0x7c, 0x6f, 0x0f, 0xb7, 0x19, 0x0f, 0xb7, 0x51, 0x02, 0x66, 0x31, 0xda, + 0x66, 0x83, 0xfa, 0xff, 0x75, 0x5f, 0x83, 0xc1, 0x04, 0x89, 0x4c, 0x24, 0x20, 0x85, 0xdb, 0x74, + 0x1d, 0x8b, 0x4c, 0x24, 0x20, 0x8b, 0x54, 0x24, 0x38, 0x8d, 0x71, 0x01, 0x8d, 0x7a, 0x01, 0x4b, + 0x89, 0x74, 0x24, 0x20, 0x8a, 0x09, 0x89, 0x7c, 0x24, 0x38, 0x88, 0x0a, 0x75, 0xe3, 0x31, 0xc0, + 0x89, 0x44, 0x24, 0x28, 0x89, 0x44, 0x24, 0x2c, 0xf6, 0x44, 0x24, 0x0c, 0x01, 0x0f, 0x84, 0x4f, + 0xfa, 0xff, 0xff, 0x31, 0xc0, 0x83, 0x7c, 0x24, 0x30, 0x00, 0x0f, 0x94, 0xc0, 0x8d, 0x44, 0x40, + 0xfd, 0xeb, 0x12, 0x89, 0x44, 0x24, 0x08, 0xeb, 0x08, 0xc7, 0x44, 0x24, 0x08, 0xfd, 0xff, 0xff, + 0xff, 0x8b, 0x44, 0x24, 0x08, 0x81, 0xc4, 0x44, 0x06, 0x00, 0x00, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, + 0x55, 0x53, 0x57, 0x56, 0x89, 0xce, 0x8b, 0x59, 0x0c, 0x39, 0xd3, 0x7d, 0x2f, 0x8b, 0x0e, 0x8b, + 0x46, 0x04, 0x39, 0xc1, 0x74, 0x13, 0x8d, 0x79, 0x01, 0x89, 0x3e, 0x0f, 0xb6, 0x29, 0x89, 0xd9, + 0xd3, 0xe5, 0x09, 0x6e, 0x08, 0x89, 0xf9, 0xeb, 0x09, 0xc7, 0x46, 0x10, 0x01, 0x00, 0x00, 0x00, + 0x89, 0xc1, 0x83, 0xc3, 0x08, 0x89, 0x5e, 0x0c, 0x39, 0xd3, 0x7c, 0xd6, 0x8b, 0x7e, 0x08, 0x31, + 0xc0, 0x48, 0x89, 0xd1, 0xd3, 0xe0, 0xf7, 0xd0, 0x21, 0xf8, 0xd3, 0xef, 0x89, 0x7e, 0x08, 0x29, + 0xd3, 0x89, 0x5e, 0x0c, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x53, 0x57, 0x56, 0x83, 0xec, 0x08, + 0x89, 0xd5, 0x89, 0xcf, 0xe8, 0x22, 0x01, 0x00, 0x00, 0xb9, 0xfd, 0xff, 0xff, 0xff, 0x83, 0x7f, + 0x10, 0x00, 0x0f, 0x85, 0x05, 0x01, 0x00, 0x00, 0x8b, 0x74, 0x24, 0x1c, 0x89, 0x2c, 0x24, 0x3d, + 0xff, 0x00, 0x00, 0x00, 0x77, 0x10, 0x8b, 0x4f, 0x18, 0x8d, 0x51, 0x01, 0x89, 0x57, 0x18, 0x88, + 0x01, 0xe9, 0xcf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x01, 0x00, 0x00, 0x0f, 0x84, 0xe6, 0x00, 0x00, + 0x00, 0x3b, 0x85, 0x60, 0x02, 0x00, 0x00, 0x0f, 0x8f, 0xcb, 0x00, 0x00, 0x00, 0x3d, 0x1d, 0x01, + 0x00, 0x00, 0x0f, 0x87, 0xc0, 0x00, 0x00, 0x00, 0x83, 0xbe, 0x60, 0x02, 0x00, 0x00, 0xff, 0x0f, + 0x84, 0xb3, 0x00, 0x00, 0x00, 0x0f, 0xb7, 0x8c, 0x00, 0xe6, 0x07, 0x07, 0x00, 0x89, 0x4c, 0x24, + 0x04, 0x05, 0xff, 0xfe, 0xff, 0xff, 0x31, 0xf6, 0xb9, 0xff, 0x00, 0x00, 0x10, 0x0f, 0xa3, 0xc1, + 0x72, 0x10, 0x0f, 0xb6, 0x90, 0xca, 0x09, 0x07, 0x00, 0x89, 0xf9, 0xe8, 0x10, 0xff, 0xff, 0xff, + 0x89, 0xc6, 0x89, 0xf9, 0x8b, 0x5c, 0x24, 0x1c, 0x89, 0xda, 0xe8, 0x8c, 0x00, 0x00, 0x00, 0x83, + 0xf8, 0x1d, 0x77, 0x74, 0x89, 0xc1, 0x3b, 0x83, 0x60, 0x02, 0x00, 0x00, 0x7f, 0x6a, 0x0f, 0xb7, + 0xac, 0x09, 0x42, 0x0a, 0x07, 0x00, 0x31, 0xc0, 0x83, 0xf9, 0x04, 0x72, 0x0e, 0x0f, 0xb6, 0x91, + 0x24, 0x0a, 0x07, 0x00, 0x89, 0xf9, 0xe8, 0xd5, 0xfe, 0xff, 0xff, 0x01, 0xe8, 0x8b, 0x4f, 0x18, + 0x89, 0xca, 0x2b, 0x57, 0x14, 0x39, 0xd0, 0x7f, 0x3f, 0x03, 0x74, 0x24, 0x04, 0x85, 0xf6, 0x7e, + 0x18, 0xf7, 0xd8, 0x31, 0xc9, 0x8b, 0x57, 0x18, 0x8d, 0x2c, 0x0a, 0x8a, 0x1c, 0x28, 0x88, 0x1c, + 0x0a, 0x41, 0x39, 0xce, 0x75, 0xef, 0x8b, 0x4f, 0x18, 0x01, 0xf1, 0x89, 0x4f, 0x18, 0x8b, 0x2c, + 0x24, 0x8b, 0x74, 0x24, 0x1c, 0x89, 0xf9, 0x89, 0xea, 0xe8, 0x1d, 0x00, 0x00, 0x00, 0x83, 0x7f, + 0x10, 0x00, 0x0f, 0x84, 0x07, 0xff, 0xff, 0xff, 0xb9, 0xfd, 0xff, 0xff, 0xff, 0x89, 0xc8, 0x83, + 0xc4, 0x08, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x31, 0xc9, 0xeb, 0xf2, 0x55, 0x53, 0x57, 0x56, 0x50, + 0x89, 0xd5, 0x89, 0xcb, 0x31, 0xd2, 0x42, 0xe8, 0x64, 0xfe, 0xff, 0xff, 0x89, 0xc7, 0x0f, 0xb7, + 0x45, 0x02, 0x31, 0xf6, 0x39, 0xc7, 0x89, 0x2c, 0x24, 0x7c, 0x21, 0x83, 0xc5, 0x04, 0x31, 0xf6, + 0x01, 0xc6, 0x29, 0xc7, 0x89, 0xd9, 0x31, 0xd2, 0x42, 0xe8, 0x42, 0xfe, 0xff, 0xff, 0x8d, 0x3c, + 0x78, 0x0f, 0xb7, 0x45, 0x00, 0x83, 0xc5, 0x02, 0x39, 0xc7, 0x7d, 0xe4, 0x01, 0xfe, 0x8b, 0x04, + 0x24, 0x0f, 0xb7, 0x44, 0x70, 0x20, 0x83, 0xc4, 0x04, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x53, + 0x57, 0x56, 0x83, 0xec, 0x20, 0x8b, 0x7c, 0x24, 0x34, 0xb8, 0xe0, 0xff, 0xff, 0xff, 0x66, 0xc7, + 0x44, 0x01, 0x20, 0x00, 0x00, 0x83, 0xc0, 0x02, 0x75, 0xf4, 0xc7, 0x81, 0x60, 0x02, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x85, 0xff, 0x74, 0x1b, 0x31, 0xc0, 0x80, 0x3c, 0x02, 0x00, 0x74, 0x0e, + 0x89, 0x81, 0x60, 0x02, 0x00, 0x00, 0x0f, 0xb6, 0x34, 0x02, 0x66, 0xff, 0x04, 0x71, 0x40, 0x39, + 0xc7, 0x75, 0xe7, 0x31, 0xff, 0x31, 0xdb, 0x43, 0xbd, 0xe0, 0xff, 0xff, 0xff, 0xb8, 0xfd, 0xff, + 0xff, 0xff, 0x0f, 0xb7, 0x74, 0x29, 0x20, 0x29, 0xf3, 0x72, 0x66, 0x01, 0xdb, 0x66, 0x89, 0x7c, + 0x2c, 0x20, 0x01, 0xf7, 0x83, 0xc5, 0x02, 0x75, 0xe9, 0x83, 0xff, 0x02, 0x72, 0x04, 0x85, 0xdb, + 0x75, 0x4f, 0x83, 0xff, 0x01, 0x75, 0x07, 0x66, 0x83, 0x79, 0x02, 0x01, 0x75, 0x43, 0x8b, 0x5c, + 0x24, 0x34, 0x85, 0xdb, 0x74, 0x23, 0x31, 0xc0, 0x0f, 0xb6, 0x34, 0x02, 0x85, 0xf6, 0x74, 0x14, + 0x0f, 0xb7, 0x1c, 0x74, 0x8d, 0x6b, 0x01, 0x66, 0x89, 0x2c, 0x74, 0x66, 0x89, 0x44, 0x59, 0x20, + 0x8b, 0x5c, 0x24, 0x34, 0x40, 0x39, 0xc3, 0x75, 0xdf, 0x31, 0xc0, 0x83, 0xff, 0x01, 0x75, 0x11, + 0x66, 0xc7, 0x41, 0x02, 0x02, 0x00, 0x8b, 0x91, 0x60, 0x02, 0x00, 0x00, 0x42, 0x66, 0x89, 0x51, + 0x22, 0x83, 0xc4, 0x20, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x00, 0x7f, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x11, 0x00, + 0x13, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x2b, 0x00, 0x33, 0x00, 0x3b, 0x00, + 0x43, 0x00, 0x53, 0x00, 0x63, 0x00, 0x73, 0x00, 0x83, 0x00, 0xa3, 0x00, 0xc3, 0x00, 0xe3, 0x00, + 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, + 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0d, 0x0d, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, + 0x0d, 0x00, 0x11, 0x00, 0x19, 0x00, 0x21, 0x00, 0x31, 0x00, 0x41, 0x00, 0x61, 0x00, 0x81, 0x00, + 0xc1, 0x00, 0x01, 0x01, 0x81, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x01, 0x06, 0x01, 0x08, + 0x01, 0x0c, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x01, 0x30, 0x01, 0x40, 0x01, 0x60, 0x10, 0x11, + 0x12, 0x00, 0x08, 0x07, 0x09, 0x06, 0x0a, 0x05, 0x0b, 0x04, 0x0c, 0x03, 0x0d, 0x02, 0x0e, 0x01, + 0x0f, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x95, 0xbd, 0x09, 0x58, 0x14, 0x57, + 0xb6, 0x38, 0x5e, 0x05, 0x0d, 0x36, 0xd8, 0x5a, 0x8d, 0x12, 0x03, 0x8a, 0xda, 0x1a, 0x4c, 0x64, + 0xe2, 0x28, 0x1d, 0x8d, 0x11, 0x97, 0x84, 0xad, 0x40, 0x8d, 0xad, 0x0d, 0x6d, 0x37, 0x4e, 0x12, + 0x62, 0x88, 0x80, 0x0d, 0x51, 0x21, 0x74, 0x97, 0x4b, 0x22, 0xa6, 0xb1, 0xe8, 0x84, 0x4b, 0xa5, + 0x9c, 0x4c, 0x96, 0x79, 0x99, 0x79, 0x93, 0x37, 0xc9, 0x8b, 0x99, 0xc9, 0x2c, 0x79, 0x3a, 0x4b, + 0x14, 0x13, 0x97, 0x6e, 0xf0, 0x01, 0x2e, 0xa3, 0xa0, 0x8e, 0xe2, 0xf2, 0x0c, 0x26, 0x4c, 0x52, + 0xa4, 0x79, 0x49, 0x03, 0x0e, 0x20, 0x1a, 0xfa, 0x7f, 0xce, 0xad, 0x6e, 0x81, 0xcc, 0xcc, 0xfb, + 0x7d, 0x7f, 0xbf, 0x14, 0x5d, 0x77, 0x3b, 0xf7, 0xdc, 0xb3, 0xdd, 0x73, 0xee, 0x52, 0xb9, 0x93, + 0xec, 0x39, 0xa6, 0x70, 0x1a, 0xe6, 0xd0, 0xdb, 0x9b, 0x34, 0x4c, 0x55, 0x27, 0xbe, 0xf6, 0xfe, + 0x96, 0x63, 0xef, 0xf9, 0x9d, 0x9f, 0x61, 0xbe, 0xbe, 0x0f, 0xfe, 0xc4, 0x31, 0x75, 0x06, 0x86, + 0x61, 0xf6, 0xb4, 0xed, 0xf1, 0xec, 0x69, 0xdf, 0xa3, 0xec, 0x69, 0xe9, 0x7c, 0x48, 0xcf, 0x30, + 0xa7, 0x43, 0xff, 0xac, 0xe4, 0x6f, 0x36, 0xb1, 0x2b, 0x92, 0x5c, 0x2c, 0x6e, 0xe2, 0xfb, 0x02, + 0xe1, 0x4d, 0xfc, 0x00, 0x54, 0x66, 0x64, 0xbe, 0x8f, 0x9c, 0x1c, 0xbc, 0x73, 0x98, 0xd9, 0xc9, + 0x30, 0xc7, 0xf0, 0xcf, 0x21, 0x26, 0x8c, 0x61, 0x7a, 0xf7, 0x72, 0x6c, 0x5c, 0xa9, 0xd6, 0xbe, + 0x03, 0xc0, 0x9e, 0xaa, 0xd3, 0x8f, 0x80, 0xc9, 0x19, 0x3c, 0x89, 0x43, 0xdc, 0x4c, 0x4f, 0x71, + 0xdd, 0xdb, 0x50, 0x56, 0xca, 0x98, 0x4f, 0x19, 0x3d, 0xc3, 0xa5, 0xb7, 0x4b, 0x19, 0x3b, 0xb3, + 0xf3, 0xd4, 0x23, 0x0c, 0xf3, 0x14, 0x8b, 0xd0, 0x99, 0x00, 0xe3, 0x7a, 0x4e, 0xa3, 0xe2, 0xc0, + 0xb1, 0x53, 0x07, 0x11, 0xd5, 0x33, 0xf0, 0x47, 0xcb, 0x7c, 0x1f, 0x28, 0xf7, 0x89, 0x9f, 0x01, + 0xb0, 0x5f, 0x7f, 0x0d, 0xa5, 0xa3, 0x20, 0xde, 0xf4, 0x7d, 0x17, 0x08, 0x47, 0x50, 0xb5, 0x99, + 0x89, 0x9a, 0xff, 0x14, 0xbb, 0x19, 0x46, 0xca, 0x4c, 0xd4, 0xbe, 0x7f, 0x53, 0x7d, 0xd1, 0xbd, + 0x3f, 0x00, 0x2f, 0x1c, 0x1b, 0x71, 0x87, 0xfe, 0x8c, 0xd3, 0xf4, 0xe0, 0xcf, 0x54, 0x1d, 0xfc, + 0x58, 0x6c, 0x79, 0xd6, 0xaf, 0x97, 0x74, 0xff, 0xb3, 0xce, 0xe8, 0x08, 0xbe, 0xb6, 0x76, 0xd3, + 0xae, 0x5a, 0x16, 0x16, 0x93, 0xfb, 0xfd, 0xdd, 0x0b, 0x8b, 0xa5, 0xfb, 0x07, 0xba, 0xb9, 0xdf, + 0x70, 0xef, 0x8d, 0x99, 0x5e, 0xfc, 0x4e, 0x71, 0x7e, 0xf1, 0xfa, 0xe2, 0xa7, 0x8b, 0x9f, 0x28, + 0xfe, 0x51, 0xf1, 0x93, 0xc5, 0xeb, 0xb0, 0xcc, 0xdf, 0x7d, 0xfb, 0x2f, 0xcc, 0xe0, 0x70, 0xdd, + 0x9b, 0xdd, 0xc5, 0x1b, 0xe5, 0xc2, 0xc4, 0xd9, 0xc5, 0xe6, 0x62, 0x4b, 0x71, 0x4e, 0x71, 0x6e, + 0xb1, 0xad, 0x38, 0xaf, 0xd8, 0x5a, 0xfc, 0x8b, 0x69, 0x91, 0xdc, 0xbb, 0xdc, 0x87, 0x6a, 0x8b, + 0x85, 0xc5, 0x1c, 0x3b, 0xe9, 0x0e, 0xfd, 0x99, 0xa6, 0xe9, 0x81, 0x8e, 0x75, 0x2c, 0x76, 0x7c, + 0xa6, 0x3b, 0x8e, 0x29, 0x06, 0x5e, 0x0d, 0xe3, 0x94, 0xbf, 0xfe, 0xe9, 0x27, 0x1b, 0x5e, 0x1b, + 0xfd, 0x8f, 0xf9, 0x3f, 0xfe, 0xa9, 0x14, 0x09, 0xfd, 0xfb, 0xc5, 0xdc, 0xe2, 0x40, 0xe4, 0x84, + 0x9e, 0x77, 0xe6, 0x06, 0xe6, 0x4e, 0xea, 0x91, 0xee, 0x41, 0x21, 0x20, 0xf7, 0x4c, 0x02, 0x12, + 0x34, 0x45, 0xe0, 0xfb, 0x64, 0x78, 0x93, 0xd6, 0x26, 0x6a, 0x9a, 0x22, 0x26, 0xf4, 0xa8, 0x0d, + 0x80, 0x5e, 0x8b, 0x7a, 0x29, 0xbd, 0x52, 0xe9, 0xcf, 0xd4, 0xe5, 0xbd, 0x41, 0x7a, 0x3d, 0xd7, + 0xf3, 0xaf, 0xe9, 0xe5, 0xee, 0xf9, 0x1e, 0x6b, 0x1a, 0x23, 0x57, 0xf7, 0x32, 0x8d, 0x91, 0xb9, + 0xf8, 0xc7, 0xd6, 0xcb, 0x14, 0xa7, 0x4c, 0x9a, 0xd0, 0xe3, 0x9c, 0x8b, 0xc4, 0xf8, 0x33, 0x9b, + 0xec, 0xf9, 0xcb, 0x24, 0x24, 0x9f, 0xb3, 0xd3, 0x08, 0x6f, 0xff, 0x99, 0xdb, 0x5b, 0x73, 0xbf, + 0xad, 0xb7, 0x8e, 0x09, 0xfb, 0xcb, 0xa4, 0x0f, 0x35, 0xce, 0x68, 0x6c, 0xa9, 0x71, 0x41, 0xcb, + 0x67, 0x06, 0x29, 0x8d, 0x16, 0xf5, 0x52, 0x1a, 0xa5, 0xf6, 0x72, 0x86, 0x06, 0xd7, 0x29, 0x20, + 0x52, 0xc3, 0xd7, 0xbd, 0x3d, 0x40, 0xa4, 0x4f, 0x81, 0x48, 0x57, 0xf7, 0x34, 0xec, 0xf9, 0x62, + 0x8f, 0x6f, 0xcf, 0x79, 0x24, 0x92, 0x44, 0xc7, 0x45, 0xe8, 0x18, 0x5d, 0xcb, 0xa0, 0x53, 0x86, + 0x71, 0x4e, 0x09, 0x3c, 0x0c, 0x78, 0x30, 0x81, 0x87, 0x73, 0xe9, 0x5f, 0xcc, 0x54, 0xb8, 0x64, + 0x96, 0x11, 0x8f, 0xeb, 0x1a, 0x8c, 0x9e, 0x86, 0xff, 0x9b, 0x76, 0xf8, 0x4f, 0xd5, 0x0f, 0x90, + 0x26, 0xcd, 0xfb, 0xcc, 0x4d, 0x86, 0x69, 0x00, 0xf2, 0x68, 0x6e, 0x52, 0xf2, 0xe8, 0xe8, 0xcf, + 0xd4, 0xd8, 0x9b, 0x2a, 0x79, 0xe4, 0x4d, 0x89, 0xb1, 0x5f, 0xef, 0xe9, 0xfd, 0xd7, 0x24, 0xfa, + 0xb0, 0x57, 0x15, 0xa9, 0x50, 0xd1, 0xed, 0xc0, 0x56, 0x4d, 0x60, 0xab, 0x36, 0xb0, 0x95, 0x09, + 0x4c, 0x63, 0x6e, 0x8a, 0xc7, 0x23, 0x07, 0xe7, 0xe2, 0x70, 0x35, 0x37, 0xf1, 0x67, 0x9a, 0xee, + 0xe6, 0xf0, 0x70, 0x3f, 0xef, 0xfd, 0xfe, 0x70, 0x67, 0x05, 0x02, 0x0c, 0x33, 0x42, 0x30, 0xfe, + 0xb5, 0x1c, 0x80, 0x66, 0x5b, 0xf2, 0x6c, 0x62, 0xc7, 0x80, 0xd8, 0x15, 0x27, 0xf1, 0x3a, 0xc9, + 0x14, 0x4b, 0xce, 0x78, 0xbf, 0x99, 0x4e, 0x4e, 0x7a, 0x07, 0xa7, 0x1b, 0x5b, 0xe7, 0x5b, 0xf5, + 0x6c, 0x8f, 0xd8, 0xca, 0x90, 0x46, 0xcc, 0xeb, 0x27, 0xce, 0x44, 0x0d, 0xbc, 0x0e, 0x4d, 0x37, + 0xfa, 0xa5, 0x7c, 0xad, 0xb1, 0x97, 0xbd, 0x2d, 0xb6, 0x30, 0xf2, 0xce, 0x44, 0x6d, 0x5e, 0x4e, + 0xae, 0xd9, 0xa2, 0x2c, 0x06, 0xbd, 0x15, 0x8f, 0xc7, 0xca, 0xa0, 0x63, 0x92, 0x59, 0x63, 0xec, + 0x99, 0x9f, 0x1c, 0x0e, 0x0d, 0xc4, 0x73, 0x0c, 0xf1, 0xcb, 0x45, 0x37, 0x9f, 0x5e, 0xff, 0x64, + 0x7e, 0x43, 0xb0, 0xbb, 0x2e, 0x9d, 0x64, 0x8d, 0xe5, 0x8e, 0x98, 0xf4, 0x75, 0x8f, 0xa1, 0x48, + 0x65, 0x36, 0x8b, 0xdd, 0xd3, 0x45, 0xaf, 0x81, 0x3b, 0x72, 0x45, 0xec, 0x9d, 0xee, 0x3e, 0xc7, + 0x65, 0x5e, 0x86, 0x42, 0xed, 0xdd, 0x7c, 0x40, 0x8c, 0x3b, 0xd2, 0x22, 0xf6, 0x4c, 0x77, 0x7b, + 0xb8, 0xcc, 0x56, 0x72, 0x3d, 0xe9, 0xa2, 0xf1, 0x04, 0xe9, 0x17, 0x87, 0x1e, 0x3b, 0x4a, 0x25, + 0xf2, 0x95, 0x8f, 0xe1, 0xaf, 0xa0, 0x95, 0x4c, 0xda, 0xce, 0xdf, 0xa0, 0xfc, 0x56, 0xfa, 0x25, + 0x93, 0x7f, 0xc8, 0x2b, 0x55, 0x6a, 0xc9, 0x10, 0xf7, 0x51, 0x23, 0xb1, 0x76, 0x91, 0xfa, 0xf3, + 0x5f, 0xf7, 0x01, 0x7c, 0xbe, 0xe7, 0x10, 0x6d, 0xc1, 0xb7, 0x42, 0x0d, 0x57, 0xf7, 0x63, 0xc4, + 0x84, 0x55, 0xb9, 0x0f, 0x06, 0xe0, 0xef, 0xf9, 0xaf, 0xc8, 0xad, 0x3e, 0xde, 0x0f, 0x95, 0x9a, + 0x9a, 0x78, 0x05, 0xab, 0x1d, 0x53, 0xeb, 0x9e, 0xed, 0x3f, 0x1f, 0x9e, 0xdf, 0x45, 0x3e, 0x33, + 0x5e, 0x25, 0x95, 0x5d, 0xdc, 0xde, 0x1e, 0x96, 0xdb, 0xdb, 0x08, 0x4f, 0x33, 0x3b, 0x96, 0x57, + 0xd8, 0x13, 0x51, 0x97, 0x01, 0x08, 0x69, 0xed, 0x6f, 0x25, 0xbd, 0xfd, 0xe7, 0xa5, 0x4a, 0x3d, + 0x7b, 0x5b, 0xaa, 0x8c, 0x8d, 0xb9, 0x45, 0x4e, 0x79, 0x7d, 0xd3, 0xbd, 0xb7, 0xa6, 0x93, 0xb3, + 0xf7, 0x55, 0xc6, 0xde, 0x67, 0xd2, 0x27, 0x9d, 0x81, 0x2e, 0xe2, 0x07, 0xa5, 0xca, 0xae, 0x6c, + 0xa1, 0x0e, 0x1b, 0xcb, 0xba, 0xc7, 0x49, 0x23, 0x69, 0x26, 0x3d, 0x20, 0x6a, 0xa3, 0x48, 0xa3, + 0x95, 0xf8, 0x58, 0x80, 0x23, 0x59, 0x75, 0x40, 0x63, 0x49, 0x88, 0x73, 0x9f, 0x73, 0xfe, 0xc0, + 0x1d, 0x70, 0xa6, 0xba, 0x3d, 0xce, 0xe7, 0xb8, 0x23, 0x1e, 0xd1, 0x3f, 0x9d, 0x3b, 0x72, 0x12, + 0xe8, 0x92, 0xd4, 0x2c, 0x0e, 0x18, 0xb8, 0xdd, 0x1f, 0x02, 0x8e, 0xee, 0x3e, 0x67, 0x1c, 0x99, + 0x46, 0x6c, 0x1a, 0x5f, 0x0c, 0xd4, 0xda, 0x06, 0xc9, 0x28, 0x32, 0xad, 0x29, 0x4b, 0x83, 0xf8, + 0x1b, 0xaf, 0x1a, 0xcf, 0x75, 0x7e, 0x0c, 0x9c, 0x01, 0xda, 0x55, 0xef, 0xc7, 0xca, 0x57, 0xb9, + 0xea, 0xcb, 0x68, 0xbd, 0x97, 0x07, 0xdc, 0xcd, 0x9c, 0xfb, 0x1b, 0xb5, 0xfd, 0x98, 0x19, 0xad, + 0x00, 0x61, 0xb5, 0x86, 0x3b, 0xdc, 0x7c, 0xfe, 0x6b, 0x72, 0xde, 0x77, 0x52, 0x5e, 0x13, 0x70, + 0x9f, 0xe5, 0xdc, 0xa2, 0x5a, 0x3c, 0x76, 0xc6, 0x65, 0x32, 0x3e, 0x08, 0x51, 0x0c, 0xb0, 0x5c, + 0xf5, 0x06, 0x80, 0xc8, 0x1d, 0x3e, 0x4b, 0x2e, 0x9e, 0xff, 0x9a, 0xfb, 0xa8, 0xb7, 0x73, 0x2d, + 0x24, 0x49, 0x9b, 0xf1, 0x5c, 0x7f, 0x3f, 0x69, 0x35, 0x9e, 0x73, 0xf7, 0x91, 0x06, 0xae, 0x3a, + 0x15, 0xf3, 0x42, 0x8d, 0x3a, 0x1f, 0xc2, 0x94, 0x37, 0xb5, 0x89, 0xef, 0xa2, 0x30, 0x06, 0x0c, + 0xce, 0x55, 0xae, 0xee, 0xe9, 0x48, 0xbb, 0xeb, 0x48, 0xfc, 0x2f, 0xc9, 0x25, 0xe2, 0x3d, 0xff, + 0x2d, 0xbe, 0x7e, 0x4e, 0x78, 0x3f, 0xbc, 0xfb, 0xa2, 0xae, 0x74, 0xfe, 0x18, 0x5b, 0xe2, 0x5c, + 0xc3, 0x1d, 0x69, 0x1a, 0x39, 0x70, 0xcf, 0x8c, 0x61, 0x38, 0x9c, 0xfb, 0x06, 0xbc, 0x34, 0x01, + 0xe7, 0x70, 0xb4, 0x01, 0xdf, 0x33, 0xc4, 0x4b, 0x5a, 0x00, 0x93, 0x6e, 0xd2, 0xe0, 0xee, 0xe3, + 0xaa, 0x87, 0x86, 0x02, 0x01, 0xa0, 0x4c, 0x53, 0x24, 0xc5, 0xc2, 0x0f, 0xa9, 0xef, 0x13, 0x71, + 0x3a, 0x27, 0x7e, 0x0a, 0xd9, 0xf2, 0x72, 0x16, 0xb0, 0x59, 0x30, 0x9d, 0x5c, 0x87, 0xce, 0x01, + 0x1d, 0x44, 0xe5, 0x5b, 0x78, 0xfd, 0x1c, 0x5f, 0x00, 0x99, 0x60, 0x8f, 0xa4, 0xd7, 0x78, 0x42, + 0x12, 0xfc, 0x12, 0xdf, 0x45, 0x04, 0x3f, 0xb7, 0xf7, 0x12, 0x48, 0xc2, 0x15, 0x78, 0x1a, 0x58, + 0x92, 0xdf, 0xc5, 0x7a, 0xa2, 0x9a, 0xc9, 0x45, 0x32, 0xd8, 0x7f, 0x8e, 0x74, 0xf7, 0xb7, 0x4a, + 0xf9, 0x7a, 0xf6, 0x32, 0x28, 0x54, 0xcc, 0x49, 0xd2, 0xea, 0xed, 0x9c, 0x0e, 0x0a, 0x45, 0xce, + 0xdf, 0x97, 0x1f, 0x7b, 0x9f, 0x55, 0x9f, 0x74, 0x91, 0xf4, 0x00, 0x8c, 0xf8, 0xcf, 0xa4, 0xfc, + 0xae, 0xd5, 0xc2, 0x41, 0x6c, 0xcd, 0x7a, 0x90, 0xd5, 0x7d, 0xce, 0x08, 0x32, 0x89, 0xec, 0xd2, + 0x88, 0xed, 0x43, 0x51, 0x5e, 0x72, 0x85, 0x9c, 0x22, 0x6d, 0xe2, 0x71, 0x2d, 0x15, 0x0f, 0x4a, + 0x14, 0x47, 0x42, 0xdf, 0x65, 0xe8, 0xe0, 0x0a, 0xd0, 0xa8, 0x1f, 0xc9, 0x05, 0xa4, 0x27, 0x97, + 0xc9, 0x79, 0x72, 0xb2, 0x73, 0x63, 0x00, 0x86, 0xd9, 0x08, 0xa5, 0x6d, 0xe7, 0xdb, 0x09, 0xe0, + 0x06, 0x95, 0x5d, 0xde, 0x76, 0xee, 0xa3, 0xf3, 0x50, 0xed, 0xeb, 0xce, 0xbf, 0xc1, 0xf8, 0x42, + 0xf2, 0xa5, 0xff, 0xff, 0xa7, 0x7a, 0x02, 0xa8, 0xde, 0x90, 0xd8, 0x3f, 0x1d, 0x68, 0x99, 0x79, + 0x8b, 0x5c, 0x4e, 0xba, 0x25, 0xde, 0x7a, 0x6c, 0x6b, 0xb4, 0xc4, 0x6b, 0x49, 0x4f, 0x27, 0xca, + 0x9e, 0xd1, 0x03, 0x19, 0x9f, 0x50, 0x4d, 0xa9, 0x7e, 0x1b, 0xe9, 0x93, 0xef, 0x27, 0xa7, 0x86, + 0xbc, 0xa4, 0x52, 0x41, 0xfd, 0x1b, 0xe0, 0x3e, 0xf2, 0x93, 0x9e, 0xa0, 0xf2, 0xd5, 0x87, 0x94, + 0xcf, 0xd5, 0xfb, 0x18, 0xb9, 0xcc, 0x7d, 0x30, 0x74, 0xfe, 0x2b, 0xa0, 0x6d, 0x5f, 0x03, 0x14, + 0xf5, 0x37, 0xf1, 0x1d, 0x58, 0xf8, 0xa9, 0x5a, 0xe3, 0x36, 0x68, 0x5a, 0x7f, 0x6b, 0xb8, 0x49, + 0x01, 0x9d, 0x03, 0xfd, 0xdc, 0x5b, 0x0f, 0x14, 0xf6, 0xb3, 0x92, 0x09, 0xd4, 0xef, 0x0c, 0x3b, + 0x56, 0xe8, 0x50, 0xd5, 0xae, 0x8b, 0xaa, 0x5d, 0xc3, 0xff, 0xa9, 0x76, 0xcd, 0x54, 0xed, 0xd2, + 0x84, 0x3a, 0xf1, 0xb8, 0x7e, 0x94, 0x9a, 0x2d, 0x92, 0x2a, 0xc1, 0xe0, 0x69, 0xa5, 0xd4, 0x58, + 0x6e, 0x5f, 0xd3, 0x32, 0xd6, 0x05, 0xdd, 0x8a, 0x88, 0x1f, 0x50, 0x47, 0x12, 0xf4, 0xef, 0xa1, + 0x8b, 0xe4, 0xf6, 0x08, 0x93, 0xec, 0x0c, 0x94, 0x90, 0xf3, 0xca, 0x2b, 0xcb, 0xe0, 0xe7, 0x8a, + 0x78, 0x5c, 0xf3, 0x3e, 0x96, 0xc8, 0xf9, 0x1d, 0xc5, 0x4d, 0xe1, 0x7a, 0xa6, 0x98, 0xbc, 0x18, + 0x46, 0xbc, 0xde, 0x4e, 0x4d, 0x31, 0x79, 0x3c, 0x52, 0x6c, 0xe7, 0x8a, 0x49, 0x86, 0x86, 0x38, + 0xb4, 0xc4, 0xa2, 0x93, 0x2b, 0x0f, 0x97, 0x26, 0x96, 0x32, 0x79, 0x4a, 0x96, 0x19, 0x8d, 0xa2, + 0xae, 0x29, 0x3b, 0x91, 0x49, 0x07, 0xe8, 0xd0, 0x23, 0x43, 0xb2, 0xe3, 0x80, 0xaf, 0xed, 0x3a, + 0x92, 0x1d, 0xeb, 0xf5, 0x41, 0xd3, 0xf5, 0x91, 0x79, 0x79, 0xa5, 0x13, 0x95, 0xbc, 0xfe, 0x40, + 0x00, 0x6a, 0x1e, 0x05, 0x1f, 0x8a, 0xe9, 0xcb, 0xd6, 0xb2, 0xc2, 0x7d, 0x60, 0xf7, 0x8c, 0x7d, + 0xa0, 0xd1, 0x93, 0x25, 0x53, 0x9c, 0x64, 0xd5, 0x72, 0xfb, 0x56, 0xc6, 0xe6, 0x04, 0x1e, 0x46, + 0x04, 0xcc, 0xca, 0xe5, 0x35, 0x14, 0x2e, 0xf1, 0x8b, 0xc7, 0x17, 0xd1, 0x81, 0xd9, 0xdf, 0x00, + 0x25, 0x2c, 0x65, 0x14, 0x29, 0x29, 0x64, 0xd5, 0xab, 0xba, 0x18, 0x50, 0x3a, 0x3b, 0x93, 0x00, + 0x93, 0xda, 0x86, 0x4c, 0xac, 0xae, 0x79, 0x7f, 0x6f, 0x8c, 0x86, 0xa9, 0x13, 0x40, 0x25, 0x6b, + 0x19, 0x59, 0x9e, 0x86, 0x42, 0x73, 0xd2, 0xfb, 0xb5, 0x86, 0xbc, 0xb5, 0x1d, 0x5e, 0xc5, 0x1b, + 0xe3, 0x89, 0xec, 0x84, 0x17, 0xd9, 0x74, 0x9a, 0x9c, 0x14, 0x3f, 0xd7, 0x11, 0xab, 0x0b, 0xc6, + 0x46, 0xe4, 0x9d, 0x98, 0x27, 0x2f, 0xa5, 0xb5, 0x69, 0xf6, 0x71, 0xcc, 0x36, 0x35, 0x73, 0x07, + 0x3c, 0x84, 0x7f, 0xdb, 0xe8, 0x49, 0xfd, 0xd4, 0x85, 0x9c, 0xe7, 0xaf, 0x11, 0xbe, 0x3d, 0xc8, + 0x48, 0x1c, 0xbc, 0x7c, 0xa4, 0x0f, 0xe4, 0x2e, 0x4f, 0xc9, 0x50, 0x51, 0x6d, 0x72, 0x4f, 0x06, + 0x08, 0xcc, 0x72, 0xa8, 0xf9, 0xce, 0x78, 0x78, 0x93, 0xdc, 0xd8, 0x69, 0x31, 0x71, 0xdf, 0x19, + 0xc2, 0x04, 0x76, 0x4c, 0xdc, 0xd1, 0x98, 0xd5, 0xe4, 0x46, 0xcc, 0xa6, 0x31, 0x94, 0x2c, 0xa9, + 0x7d, 0x94, 0x2c, 0x7d, 0x6e, 0xd4, 0x64, 0x96, 0x73, 0x37, 0x02, 0x7d, 0xb8, 0x83, 0x6e, 0x03, + 0x22, 0xdc, 0xae, 0x41, 0xea, 0x87, 0x81, 0x28, 0x14, 0x8b, 0x47, 0x68, 0x9b, 0x8a, 0x1f, 0x70, + 0x07, 0xe5, 0xc5, 0xf0, 0xc6, 0x1d, 0x7c, 0x6b, 0x11, 0x42, 0x3c, 0x13, 0x75, 0xd1, 0x39, 0xa9, + 0xea, 0x16, 0x4e, 0x88, 0x9c, 0xfb, 0x17, 0xd0, 0xb6, 0x58, 0x1c, 0x0c, 0x70, 0xee, 0xd7, 0xc3, + 0xd0, 0x58, 0x94, 0x96, 0x2b, 0x2b, 0x33, 0x28, 0x61, 0xc0, 0x16, 0xe7, 0x2b, 0x24, 0x8e, 0x6c, + 0xd7, 0x93, 0xed, 0x0b, 0xc8, 0xf6, 0x64, 0xc9, 0x3d, 0x17, 0x51, 0x94, 0x1f, 0x42, 0x18, 0x59, + 0x8b, 0xc8, 0xea, 0xa5, 0x4d, 0x59, 0x09, 0x01, 0xcc, 0x5a, 0x46, 0x45, 0x23, 0x40, 0x25, 0x55, + 0x88, 0xa5, 0xf2, 0xa1, 0x94, 0x2c, 0x51, 0x81, 0x34, 0x51, 0xe9, 0x68, 0xe2, 0x4f, 0xeb, 0x81, + 0xf2, 0x64, 0xc0, 0xab, 0x00, 0x77, 0xf9, 0x73, 0x64, 0x80, 0x8a, 0x06, 0xdf, 0x42, 0xf2, 0xdb, + 0x48, 0xfe, 0x85, 0xd2, 0x44, 0x8b, 0x9c, 0xff, 0x0b, 0x8b, 0x32, 0x67, 0xb5, 0x4a, 0x16, 0xde, + 0x83, 0x92, 0x01, 0xd6, 0x44, 0x8a, 0x24, 0xfc, 0x9f, 0x25, 0xde, 0x45, 0xf8, 0xfd, 0x92, 0x7b, + 0x27, 0xa5, 0x0d, 0xff, 0x9f, 0xa5, 0xb3, 0x2d, 0xb2, 0x1b, 0x49, 0x6f, 0x56, 0xbe, 0x34, 0xd1, + 0x06, 0x12, 0xdf, 0x46, 0xdc, 0xe5, 0x88, 0x0a, 0x7f, 0x81, 0xb8, 0x37, 0xd1, 0x97, 0xd3, 0x92, + 0xa9, 0x85, 0xc8, 0x76, 0x4a, 0xc2, 0x42, 0xf8, 0x4b, 0xd1, 0x32, 0x7a, 0xcc, 0x79, 0x4a, 0xa3, + 0xda, 0xc8, 0x62, 0x01, 0x52, 0xfe, 0xfd, 0xa6, 0x4a, 0x4a, 0x7e, 0x2f, 0xd0, 0xf1, 0x45, 0x16, + 0x67, 0x38, 0xa8, 0x26, 0x51, 0x89, 0x72, 0xed, 0x7c, 0x34, 0xc0, 0x08, 0x11, 0x6b, 0x84, 0x3e, + 0x20, 0xcb, 0xec, 0x60, 0x97, 0x14, 0xcf, 0xb2, 0x60, 0xb7, 0x14, 0xb0, 0xa4, 0x76, 0xc2, 0x9f, + 0x26, 0xa6, 0x16, 0x89, 0x76, 0x4e, 0xf8, 0x0b, 0x12, 0x45, 0x87, 0xf0, 0x6d, 0xb4, 0x5b, 0x3b, + 0x90, 0x9a, 0xb1, 0x29, 0xa6, 0x11, 0x1d, 0xef, 0x1c, 0xd9, 0x71, 0x18, 0x8b, 0x91, 0x02, 0x54, + 0xa4, 0x4a, 0x26, 0xe5, 0x2b, 0xae, 0x9d, 0xda, 0x40, 0x40, 0x88, 0x58, 0x01, 0x5d, 0x9f, 0x48, + 0x39, 0xcb, 0x65, 0x9f, 0x05, 0xdb, 0x48, 0x56, 0xc7, 0xba, 0x4f, 0xa8, 0x13, 0x55, 0x29, 0x6b, + 0x3c, 0x91, 0x93, 0x63, 0xb6, 0x29, 0x69, 0x77, 0x10, 0x4a, 0x2c, 0x4c, 0x64, 0x6e, 0x2f, 0xe4, + 0x57, 0xed, 0x8a, 0x55, 0xd5, 0xf6, 0xc5, 0xf0, 0xd0, 0x20, 0x60, 0xe2, 0xe9, 0x0f, 0xf1, 0xe4, + 0xaf, 0x29, 0xa3, 0x78, 0x42, 0x07, 0x34, 0x82, 0x2d, 0xee, 0x74, 0x44, 0x59, 0xe5, 0x8c, 0x3b, + 0x15, 0xde, 0x8d, 0x1e, 0xe2, 0x5e, 0x4e, 0x09, 0x98, 0x09, 0x7f, 0x4b, 0x13, 0xcd, 0x32, 0xff, + 0x0b, 0xb3, 0xf2, 0xca, 0x2a, 0x3a, 0x0a, 0x77, 0x1f, 0xb0, 0x89, 0x05, 0x51, 0x01, 0x73, 0x22, + 0xb1, 0x94, 0x4d, 0xc7, 0x91, 0x4d, 0x7c, 0x33, 0xf2, 0xc8, 0x39, 0x2e, 0xf0, 0x7c, 0xac, 0x2d, + 0x4f, 0xe1, 0xd5, 0xca, 0xd8, 0xd0, 0x0c, 0xa3, 0x7e, 0xb9, 0xf7, 0xee, 0xa8, 0x85, 0x4d, 0xc6, + 0x73, 0x52, 0xe5, 0x35, 0x89, 0x6f, 0x97, 0x4c, 0x1d, 0x30, 0x3c, 0x5f, 0x05, 0x8c, 0x3b, 0xa3, + 0xea, 0x36, 0x2a, 0x28, 0xe7, 0x3e, 0x0b, 0x03, 0xeb, 0xfc, 0x2d, 0x48, 0xa4, 0xf7, 0x86, 0x86, + 0x3b, 0xe0, 0x8c, 0x09, 0xf7, 0x7e, 0xa9, 0xad, 0x1a, 0x62, 0xde, 0x0d, 0xb9, 0x20, 0xd5, 0x6b, + 0xbf, 0x03, 0xbc, 0x2e, 0xfe, 0x91, 0x05, 0x57, 0xa6, 0x18, 0x87, 0x9f, 0xfe, 0x1d, 0x0a, 0x78, + 0xa6, 0x31, 0xfa, 0x43, 0x98, 0xfe, 0x1e, 0xfe, 0x0e, 0x35, 0x21, 0xd5, 0xab, 0x80, 0xf8, 0x74, + 0x75, 0x3e, 0x00, 0x29, 0xe8, 0x00, 0x88, 0x03, 0x9e, 0x26, 0xc3, 0xbd, 0x59, 0x7f, 0xb7, 0xdb, + 0x1a, 0x9b, 0xce, 0x55, 0xd9, 0xc5, 0x08, 0xd3, 0xab, 0xcf, 0x09, 0x53, 0x96, 0x98, 0xde, 0x16, + 0x26, 0x94, 0x96, 0x07, 0x04, 0xbf, 0x12, 0x78, 0x0c, 0xb1, 0xd6, 0x76, 0x6e, 0x86, 0x61, 0xa7, + 0x11, 0x53, 0x47, 0xf5, 0x39, 0xd2, 0x08, 0x4e, 0x10, 0x8c, 0x94, 0xa4, 0x69, 0x45, 0x2a, 0xee, + 0x8c, 0x10, 0xa7, 0x1a, 0x42, 0x6b, 0x97, 0x52, 0xb9, 0x08, 0x8d, 0x64, 0x57, 0xc8, 0x14, 0x72, + 0x07, 0xea, 0x5d, 0xe0, 0x12, 0x1d, 0x38, 0xc9, 0x9e, 0x21, 0x42, 0x3b, 0xdb, 0x44, 0x2a, 0xaf, + 0x19, 0xcf, 0x19, 0x4f, 0xa4, 0x19, 0x3d, 0xcb, 0x41, 0xa7, 0xf8, 0x2e, 0x69, 0xe9, 0x5b, 0xc9, + 0xab, 0x58, 0x30, 0x7c, 0xfe, 0xa0, 0xa9, 0x45, 0x38, 0xdc, 0x2b, 0xb7, 0xd1, 0x60, 0x08, 0xaf, + 0x12, 0x6b, 0x0d, 0x31, 0x55, 0x17, 0x87, 0xb8, 0x53, 0x4c, 0x8e, 0x3c, 0x0a, 0x2f, 0x54, 0x30, + 0x82, 0x76, 0x55, 0x4e, 0xa7, 0x8a, 0x7e, 0x97, 0x4b, 0x7d, 0xe4, 0x63, 0xca, 0xa5, 0x8f, 0x91, + 0x4b, 0x9c, 0x91, 0xf0, 0xaf, 0xf5, 0x5f, 0x21, 0xd6, 0x37, 0xa9, 0xbd, 0x41, 0x69, 0xbd, 0xb8, + 0x72, 0xa4, 0x56, 0x61, 0xb7, 0xcc, 0xf7, 0xd9, 0x45, 0x45, 0xb2, 0xb3, 0x7b, 0x98, 0x39, 0xb9, + 0xec, 0x11, 0x84, 0x26, 0xbe, 0x85, 0x90, 0x19, 0x76, 0x48, 0x1c, 0x4a, 0xad, 0xf8, 0x2f, 0xce, + 0x28, 0xe5, 0xbf, 0xd6, 0x7f, 0x55, 0x32, 0xbd, 0x29, 0x5e, 0x66, 0xd8, 0x86, 0x98, 0x56, 0x49, + 0x78, 0x35, 0xa5, 0x97, 0x34, 0xc3, 0xd8, 0xe3, 0x5b, 0xb8, 0xf4, 0x56, 0xa0, 0x05, 0x97, 0xde, + 0x2b, 0x99, 0xaa, 0xb9, 0xf4, 0xb3, 0x92, 0xb5, 0x26, 0x5d, 0x1c, 0x8c, 0x02, 0x9e, 0x72, 0xee, + 0xb1, 0x00, 0xc3, 0x37, 0x9d, 0x3b, 0xc0, 0x7b, 0x81, 0x82, 0x01, 0xa3, 0xd9, 0xfe, 0x47, 0x13, + 0xcb, 0x28, 0xed, 0xf3, 0x28, 0x5a, 0x87, 0xb4, 0x38, 0xc5, 0xe4, 0x2b, 0x54, 0xc2, 0x35, 0x60, + 0xbc, 0x3d, 0x99, 0x36, 0xb3, 0x42, 0xee, 0xa7, 0x1c, 0xa8, 0xf6, 0x38, 0x35, 0x8d, 0x59, 0xa9, + 0xec, 0x7b, 0x1f, 0x82, 0x91, 0x16, 0x07, 0x52, 0xb9, 0x6a, 0x82, 0xb5, 0xc7, 0xa1, 0xcd, 0x96, + 0xcd, 0x2c, 0xb9, 0x07, 0xf3, 0xc9, 0x82, 0x2a, 0xb0, 0x5a, 0x6f, 0x3e, 0x1a, 0x14, 0xee, 0x52, + 0x06, 0xda, 0x9f, 0x9e, 0xad, 0xca, 0xdd, 0xf2, 0x70, 0xf1, 0x56, 0x18, 0xb7, 0x7b, 0xef, 0x77, + 0x48, 0xa7, 0x2c, 0x71, 0x20, 0xe0, 0x9c, 0x19, 0x82, 0xe5, 0x4c, 0xfb, 0x3e, 0x9c, 0xa5, 0x55, + 0x40, 0x9c, 0x40, 0x6a, 0x02, 0x40, 0xcb, 0x0a, 0x41, 0xb3, 0x81, 0x3c, 0x98, 0x95, 0x4a, 0x15, + 0x1c, 0xf1, 0x8a, 0xde, 0xf0, 0x2c, 0x80, 0xe8, 0xf8, 0xb8, 0x33, 0x07, 0x40, 0xda, 0xcb, 0xd7, + 0xc0, 0x40, 0xee, 0xa5, 0x03, 0xd1, 0x54, 0x1d, 0x47, 0xd1, 0x1d, 0x35, 0xf1, 0x4c, 0xb8, 0x2f, + 0x34, 0xf1, 0x28, 0xef, 0x64, 0x33, 0x0c, 0x8c, 0x66, 0x2e, 0x78, 0x0f, 0xca, 0xa3, 0x60, 0xf0, + 0x95, 0x4d, 0x60, 0x20, 0x95, 0x2f, 0xf0, 0xad, 0x00, 0x4c, 0x71, 0x7f, 0x23, 0x80, 0x0b, 0x08, + 0xf1, 0x40, 0x24, 0xad, 0x59, 0xf9, 0xf9, 0x5c, 0x0a, 0xd1, 0x17, 0x6f, 0x5f, 0x06, 0x94, 0xea, + 0x7c, 0x13, 0xdd, 0xba, 0x21, 0x56, 0x88, 0x51, 0x5a, 0x81, 0x81, 0xca, 0x21, 0xf8, 0xf3, 0xfe, + 0x1d, 0x90, 0x07, 0x5f, 0xc4, 0x7b, 0x77, 0xd4, 0x49, 0x79, 0x8c, 0x5d, 0x02, 0x4c, 0x7c, 0x5b, + 0x5c, 0xdb, 0xc7, 0x31, 0xc2, 0x32, 0xd2, 0x28, 0xa5, 0xc6, 0x41, 0x6e, 0xbf, 0xb8, 0x2b, 0x21, + 0xb0, 0xf3, 0x61, 0x63, 0x60, 0x8d, 0xf1, 0x2a, 0x77, 0x20, 0x4b, 0x67, 0x81, 0xe0, 0xc9, 0xac, + 0x7c, 0xf7, 0x43, 0x55, 0x7f, 0x3d, 0x4e, 0x18, 0x8f, 0xb2, 0x82, 0x41, 0xbc, 0x04, 0x7d, 0x76, + 0xc6, 0x92, 0x5d, 0x09, 0xbb, 0x2e, 0xfb, 0xc6, 0x40, 0xde, 0xc3, 0x34, 0x1c, 0x64, 0xf4, 0x28, + 0xe5, 0xe3, 0xec, 0x35, 0x39, 0x30, 0xc6, 0xf9, 0x2a, 0x46, 0xae, 0x65, 0x03, 0x54, 0xf6, 0x75, + 0xf6, 0xb3, 0xab, 0xe9, 0x08, 0x93, 0x67, 0x02, 0x42, 0xae, 0x6b, 0x50, 0xe3, 0xdf, 0x0f, 0x86, + 0xc6, 0x4a, 0xce, 0xd6, 0x4e, 0x65, 0x81, 0x9e, 0x8d, 0x11, 0xf8, 0x97, 0xb5, 0x3f, 0x94, 0xcb, + 0x32, 0x39, 0xca, 0x5f, 0xef, 0xa5, 0x1c, 0x25, 0x8d, 0x80, 0x58, 0xaa, 0xfd, 0x0d, 0xc8, 0xcb, + 0x53, 0xbc, 0x23, 0xf2, 0xe6, 0xd8, 0xbf, 0x5a, 0x8d, 0x79, 0x1f, 0x8d, 0xc8, 0x8b, 0xb3, 0x7f, + 0x47, 0xeb, 0xfd, 0x6c, 0x38, 0x8f, 0xab, 0xae, 0x06, 0xec, 0x6a, 0x82, 0x1d, 0x20, 0x8e, 0xac, + 0x94, 0x95, 0x20, 0xad, 0x36, 0x7c, 0xd2, 0x31, 0x3d, 0x9c, 0x31, 0xd6, 0x47, 0x9d, 0x14, 0xb2, + 0xe5, 0x7b, 0x52, 0x37, 0x31, 0x4c, 0x52, 0x0b, 0x48, 0xe9, 0xb1, 0xd4, 0xa7, 0xa0, 0x73, 0x73, + 0x29, 0x93, 0x0b, 0x3c, 0x98, 0x15, 0x87, 0x60, 0xe2, 0x6c, 0xca, 0x25, 0x0a, 0x4f, 0x53, 0x1a, + 0x6b, 0xdf, 0xfb, 0x55, 0x38, 0x63, 0x8f, 0xb3, 0x01, 0xfe, 0x5d, 0xd9, 0x21, 0xb2, 0x4c, 0xb1, + 0x4f, 0xb6, 0x00, 0x31, 0x23, 0xec, 0xdf, 0x01, 0x42, 0x4a, 0x0a, 0x25, 0x97, 0xc6, 0xe8, 0xa1, + 0x9c, 0x6d, 0x8c, 0x40, 0x02, 0xb0, 0xfb, 0x59, 0x9f, 0x5f, 0xc5, 0xc1, 0xf7, 0xe5, 0x70, 0x00, + 0x97, 0xaf, 0xb5, 0x17, 0x82, 0xc9, 0x52, 0xa2, 0x96, 0x86, 0x26, 0xd0, 0x38, 0xd1, 0xa3, 0x31, + 0x06, 0xf2, 0xec, 0x66, 0x90, 0x8c, 0x3c, 0x3b, 0x03, 0xa4, 0x83, 0xa0, 0xf0, 0xc4, 0x0c, 0x8a, + 0x06, 0x77, 0x30, 0x6b, 0xe9, 0x32, 0xcb, 0xb7, 0x40, 0xcd, 0x6c, 0x71, 0x97, 0x99, 0x71, 0xfe, + 0x50, 0xca, 0x2a, 0xfc, 0x4d, 0x0c, 0x98, 0x02, 0xa7, 0xde, 0x6c, 0xd7, 0x22, 0xd1, 0x8f, 0xce, + 0xa1, 0xc3, 0xf6, 0x3d, 0xc0, 0x7d, 0xd2, 0xae, 0x77, 0x8c, 0xb3, 0x9f, 0x44, 0xb5, 0xf9, 0x0d, + 0xcd, 0xd4, 0x14, 0x8b, 0xbb, 0x1e, 0x0d, 0x17, 0x66, 0xd9, 0x3f, 0x46, 0x09, 0x7c, 0x4b, 0xcd, + 0xa3, 0xbd, 0xc3, 0xa4, 0xb0, 0x44, 0xa5, 0xd6, 0x40, 0x28, 0x8e, 0xaa, 0x5d, 0x9d, 0x50, 0x87, + 0x7d, 0x1b, 0x03, 0xc6, 0x73, 0xdc, 0x07, 0xf5, 0xe7, 0xdb, 0xa9, 0xef, 0xd9, 0x42, 0x7e, 0xfa, + 0x54, 0x18, 0xaa, 0x9e, 0x0e, 0x4c, 0x1b, 0x79, 0x79, 0x1d, 0xbc, 0xcb, 0x7b, 0xd6, 0x61, 0x4c, + 0xd2, 0x53, 0xca, 0x94, 0x86, 0x29, 0x73, 0x69, 0xec, 0xaa, 0xb5, 0x33, 0x7a, 0x18, 0xd2, 0xc2, + 0xe0, 0x74, 0xce, 0xfb, 0x2d, 0xca, 0x8f, 0xa7, 0xd2, 0xf7, 0xe5, 0x6e, 0xcf, 0xae, 0x18, 0xee, + 0x80, 0x2e, 0x7c, 0xb9, 0x78, 0x6b, 0x9e, 0x53, 0xe3, 0x3e, 0x21, 0x7c, 0x93, 0x4a, 0x9a, 0xf2, + 0x2c, 0x68, 0x40, 0x57, 0x67, 0xa9, 0xea, 0x67, 0x52, 0x48, 0x8f, 0x45, 0x41, 0xcf, 0x02, 0x1a, + 0x54, 0x03, 0xf3, 0xfe, 0x4c, 0xe3, 0x85, 0xaa, 0x86, 0x36, 0xec, 0xe7, 0x32, 0xf6, 0x14, 0x10, + 0x14, 0x05, 0x57, 0x15, 0xa0, 0x2b, 0xee, 0x60, 0xf8, 0x2c, 0xc6, 0xcf, 0x30, 0xcb, 0xd0, 0xce, + 0x0b, 0x93, 0xb0, 0x3c, 0x0f, 0xa1, 0xfd, 0x55, 0x13, 0x34, 0x06, 0xc2, 0xff, 0xf8, 0xb6, 0x52, + 0x6b, 0x29, 0x3c, 0x4b, 0xd1, 0xc2, 0x42, 0xcb, 0x62, 0x5a, 0x28, 0xbd, 0x7c, 0x0d, 0x41, 0xbe, + 0x4c, 0xc3, 0xae, 0x6e, 0x72, 0x45, 0x59, 0x1f, 0x81, 0xc9, 0x67, 0xa0, 0xeb, 0xd2, 0x64, 0x65, + 0xdb, 0xe2, 0xa0, 0x3a, 0x93, 0x72, 0x7d, 0x53, 0x6a, 0x6c, 0xca, 0x58, 0x96, 0x69, 0x4a, 0x8d, + 0x7b, 0x0e, 0x7e, 0x24, 0xb5, 0x45, 0x76, 0x82, 0x77, 0x60, 0x3a, 0xc9, 0x36, 0xa0, 0x17, 0x9f, + 0xad, 0xe9, 0xf4, 0x80, 0x63, 0x65, 0xf7, 0x02, 0xd7, 0x94, 0xc5, 0x0f, 0xaa, 0xa4, 0x0d, 0x75, + 0xd7, 0x91, 0xa2, 0x52, 0x45, 0x25, 0xf5, 0x45, 0x35, 0x65, 0x0c, 0x74, 0xee, 0x19, 0x11, 0x4f, + 0x3c, 0x03, 0x34, 0x95, 0x04, 0x2d, 0xf1, 0x47, 0xb5, 0x71, 0xd5, 0x32, 0x80, 0x97, 0xd2, 0xcd, + 0x40, 0x39, 0xb7, 0x87, 0x98, 0x2e, 0x38, 0x93, 0xfa, 0xd2, 0x0b, 0x5d, 0xce, 0xfb, 0xb8, 0x83, + 0xbb, 0x71, 0xd6, 0x87, 0xb9, 0xcb, 0x79, 0x2f, 0xc4, 0x9d, 0xc5, 0x10, 0x78, 0xbe, 0xe9, 0x2d, + 0x16, 0x07, 0x66, 0x70, 0x6f, 0x78, 0x0c, 0xcd, 0x30, 0x4b, 0xf8, 0xc6, 0x84, 0x02, 0xba, 0xc6, + 0x80, 0x78, 0x3e, 0x40, 0xac, 0x8a, 0xf4, 0xc2, 0x1c, 0xf4, 0x5f, 0x2c, 0x36, 0xa5, 0xf9, 0x5b, + 0xb4, 0xd4, 0x7a, 0x62, 0x6d, 0x27, 0xad, 0xdc, 0xbe, 0xb3, 0x84, 0xef, 0xe8, 0xff, 0x8a, 0x3d, + 0x99, 0xd4, 0x48, 0x84, 0x6b, 0xf1, 0xe7, 0xc1, 0xa5, 0x92, 0x78, 0xa5, 0x76, 0x79, 0xc2, 0x31, + 0xca, 0xf3, 0x3e, 0x1a, 0x55, 0xd4, 0xe1, 0xd4, 0x37, 0x92, 0xfb, 0xfd, 0xc1, 0xc8, 0xe3, 0x16, + 0x08, 0x02, 0xc7, 0x7b, 0x8d, 0x57, 0x0f, 0x05, 0xc6, 0x30, 0x4c, 0xca, 0xad, 0xf8, 0x5e, 0x2e, + 0xfd, 0x22, 0x97, 0xde, 0x24, 0x56, 0xfa, 0x19, 0xa7, 0x4e, 0x32, 0x29, 0xdc, 0xc1, 0x1f, 0x3d, + 0x05, 0x11, 0x0c, 0xa2, 0xe3, 0x47, 0x9f, 0x16, 0x27, 0x4c, 0xa7, 0x4d, 0xca, 0xc7, 0xf9, 0x93, + 0xdb, 0x7b, 0x2a, 0xd2, 0x7b, 0x23, 0x92, 0x6d, 0x8e, 0xb9, 0x22, 0x9b, 0xde, 0x04, 0xa9, 0x49, + 0xcd, 0x35, 0xe7, 0x80, 0x2d, 0x0f, 0xcc, 0x57, 0x3a, 0xa6, 0x51, 0x21, 0x97, 0xf9, 0x37, 0xa5, + 0x54, 0x70, 0xd3, 0xfd, 0xfd, 0x5f, 0x11, 0x2f, 0xdb, 0x03, 0x49, 0x6e, 0xdf, 0xf6, 0x44, 0xf6, + 0x92, 0x24, 0xb4, 0x49, 0x56, 0x3f, 0xb7, 0xaf, 0x47, 0xe2, 0xaf, 0xf5, 0x7f, 0xce, 0x5e, 0x04, + 0x10, 0x43, 0xbe, 0x35, 0x77, 0xa1, 0x46, 0x78, 0x6f, 0x44, 0x0c, 0x43, 0x35, 0xdc, 0x85, 0xba, + 0x67, 0x18, 0xea, 0x72, 0x80, 0xda, 0x4d, 0x06, 0xfa, 0x6f, 0x00, 0x53, 0x5b, 0xd9, 0xee, 0x7f, + 0x00, 0x38, 0x10, 0x73, 0xa6, 0x94, 0xb1, 0x23, 0xc6, 0x36, 0x73, 0x40, 0xb8, 0x00, 0x8d, 0x73, + 0xd4, 0xc6, 0xe2, 0xf1, 0x67, 0x46, 0x84, 0x3d, 0x55, 0x5d, 0xef, 0x32, 0x34, 0x08, 0x71, 0x2d, + 0x9a, 0xc7, 0xb9, 0xd7, 0x03, 0x57, 0x21, 0xec, 0x3e, 0x93, 0x4a, 0x78, 0x45, 0xde, 0x8d, 0xca, + 0x20, 0xcb, 0x6b, 0xd1, 0x79, 0x44, 0x38, 0xe6, 0x1c, 0x65, 0x2b, 0x75, 0x8d, 0x75, 0xe0, 0xdf, + 0x83, 0x8f, 0x47, 0x1a, 0x9a, 0xf8, 0x6b, 0x34, 0x00, 0xae, 0x04, 0x37, 0x8f, 0xc5, 0xf5, 0x5b, + 0x3b, 0x0b, 0x06, 0x49, 0x29, 0x52, 0x6b, 0xc9, 0x12, 0xba, 0x7d, 0xe0, 0xe5, 0xf0, 0x0a, 0x77, + 0x40, 0xa3, 0x17, 0x07, 0xe6, 0x39, 0x0d, 0xc0, 0xee, 0x84, 0x9a, 0xdd, 0x58, 0x2b, 0xbd, 0x6a, + 0x10, 0x8b, 0x85, 0x1b, 0x30, 0xb2, 0x5a, 0xcd, 0x44, 0xf6, 0x0a, 0x84, 0x75, 0x3e, 0x24, 0x38, + 0xdb, 0xca, 0x9e, 0xc7, 0x90, 0xf1, 0xa4, 0xf1, 0x04, 0x68, 0xcc, 0x5b, 0x5e, 0x29, 0xff, 0x1a, + 0x77, 0xe0, 0x6a, 0x1d, 0x4b, 0x63, 0x53, 0xf0, 0x96, 0xaf, 0x49, 0xf9, 0x7e, 0xf6, 0x14, 0x7b, + 0x12, 0x24, 0x82, 0xdc, 0x92, 0xdf, 0x42, 0xf4, 0x94, 0x0a, 0xc4, 0x9b, 0x6f, 0x37, 0x9e, 0x83, + 0x86, 0x4b, 0xde, 0x5a, 0x87, 0x7e, 0xc0, 0xeb, 0x10, 0x88, 0x74, 0x71, 0x62, 0xb1, 0xaa, 0x0f, + 0xe7, 0x03, 0x42, 0x7b, 0x9e, 0xec, 0xc6, 0xca, 0x66, 0x10, 0xa2, 0x52, 0x98, 0x07, 0x5c, 0x11, + 0xaa, 0x19, 0x3a, 0x90, 0x15, 0x99, 0x6a, 0x56, 0xac, 0x8f, 0x04, 0x35, 0x44, 0x4d, 0x53, 0x47, + 0xf9, 0x9d, 0x74, 0x75, 0xd6, 0xcb, 0xef, 0x90, 0x2d, 0x5a, 0xcc, 0x27, 0xb7, 0x00, 0x4c, 0x40, + 0x68, 0x93, 0xdf, 0x41, 0x40, 0x16, 0xe3, 0x55, 0x0b, 0x98, 0xb3, 0x45, 0x2a, 0x1c, 0xd7, 0x32, + 0x34, 0x87, 0x4c, 0xdd, 0x04, 0x03, 0xcb, 0x1c, 0xba, 0x36, 0x9d, 0x05, 0x64, 0xbd, 0x79, 0x94, + 0x1e, 0x81, 0x16, 0xb4, 0x46, 0x0d, 0x2a, 0xe0, 0x3c, 0xe5, 0x3f, 0x17, 0xa2, 0xea, 0x43, 0x96, + 0xfb, 0xaa, 0x73, 0x12, 0x18, 0x41, 0x8d, 0x64, 0xed, 0x60, 0xeb, 0x8d, 0x1e, 0xa9, 0xb2, 0x0d, + 0x46, 0xd6, 0x89, 0x11, 0x73, 0x1f, 0x7f, 0x8d, 0x05, 0x6b, 0xca, 0xb9, 0x31, 0x9c, 0x86, 0x50, + 0x46, 0x65, 0x02, 0x54, 0x20, 0x83, 0x60, 0x30, 0x16, 0x2a, 0x6f, 0x50, 0xb7, 0x17, 0xec, 0x05, + 0x1d, 0xd0, 0x08, 0x9b, 0x31, 0x59, 0xad, 0x49, 0x06, 0x81, 0xe3, 0x16, 0xe5, 0x1d, 0x26, 0x64, + 0x37, 0xfe, 0xea, 0x5b, 0xb8, 0x8c, 0x49, 0x85, 0x0a, 0x33, 0x55, 0xc7, 0xdc, 0xdb, 0x1e, 0x06, + 0x42, 0xd1, 0xae, 0x4c, 0x5a, 0x48, 0x6b, 0xd4, 0x85, 0x51, 0x1f, 0xc4, 0x0f, 0xa1, 0x88, 0xef, + 0x1e, 0x7b, 0x1e, 0x9a, 0xd9, 0xf4, 0x07, 0x28, 0x3d, 0xea, 0x54, 0xef, 0xc4, 0x0f, 0x38, 0x42, + 0xac, 0x0d, 0xfe, 0xb7, 0xfb, 0x1d, 0x50, 0x74, 0x71, 0x20, 0x8c, 0xab, 0x8e, 0xa2, 0x2f, 0x5a, + 0x61, 0x4e, 0x50, 0x4f, 0x47, 0x43, 0x3e, 0xfc, 0xb0, 0x6a, 0x96, 0xf8, 0xae, 0x44, 0xb6, 0xea, + 0x38, 0xca, 0x18, 0x15, 0x3a, 0x5f, 0xb7, 0xfd, 0x51, 0x98, 0x5c, 0x4a, 0x59, 0xa5, 0x6f, 0xf2, + 0xdd, 0xa5, 0xc6, 0xae, 0x58, 0x62, 0xf5, 0x8b, 0x3b, 0x34, 0x8b, 0xb9, 0x57, 0x70, 0x5d, 0x92, + 0x9c, 0x05, 0xfb, 0x21, 0xa7, 0xcd, 0x06, 0x19, 0x6c, 0x4c, 0xdb, 0xc0, 0xd4, 0xa1, 0xe9, 0x31, + 0x2b, 0x7f, 0x7e, 0x38, 0x38, 0xa9, 0xc8, 0x19, 0xe0, 0x6d, 0x77, 0x99, 0x95, 0xf7, 0x83, 0x19, + 0x0d, 0x01, 0x41, 0x17, 0x10, 0x80, 0xa1, 0x97, 0x53, 0xd5, 0xf0, 0x02, 0x2c, 0xaa, 0x4d, 0xc9, + 0x88, 0xa7, 0x89, 0x80, 0xd0, 0x65, 0x51, 0x92, 0x55, 0x5c, 0x64, 0x53, 0x3b, 0xa8, 0x88, 0x4d, + 0x09, 0x47, 0xef, 0x18, 0x1b, 0xaa, 0x90, 0x6d, 0x8a, 0x5e, 0x2d, 0xaf, 0xbe, 0xea, 0xbc, 0x8f, + 0xdc, 0x82, 0x2a, 0x68, 0x94, 0xdb, 0x95, 0xb9, 0xb7, 0x29, 0x91, 0x7d, 0x9c, 0x3d, 0x1f, 0x30, + 0x56, 0x8c, 0xf7, 0xab, 0xf3, 0xe0, 0x55, 0x5c, 0x80, 0x89, 0x1d, 0xb5, 0x70, 0xb0, 0xc0, 0xd8, + 0xd7, 0x97, 0x3e, 0x13, 0xd8, 0x75, 0x11, 0x85, 0xed, 0x92, 0x54, 0xb5, 0x8e, 0x8a, 0x63, 0x17, + 0x39, 0x23, 0xfd, 0x8c, 0x4e, 0x31, 0xe9, 0x09, 0x48, 0x16, 0xa5, 0x7b, 0x41, 0x68, 0x12, 0x11, + 0x5f, 0x4a, 0x00, 0x1f, 0x7e, 0x2f, 0x9a, 0x46, 0x10, 0xd2, 0xbd, 0x0d, 0xd3, 0xe4, 0x0c, 0x08, + 0x96, 0x9a, 0xc5, 0xdb, 0x2c, 0x40, 0x6f, 0x81, 0xb6, 0xc7, 0x21, 0xf6, 0x10, 0xa8, 0x4f, 0x58, + 0x79, 0x8d, 0xe4, 0xb7, 0x8b, 0x03, 0x63, 0xb7, 0xe9, 0x89, 0x57, 0xca, 0x7c, 0x65, 0x36, 0xd1, + 0xec, 0x21, 0xcd, 0x9d, 0xf9, 0xa8, 0x9a, 0xcb, 0x6f, 0x92, 0x7a, 0xd2, 0x9c, 0xd4, 0x46, 0xac, + 0x1d, 0x72, 0xec, 0x4f, 0x89, 0xb5, 0xcd, 0xb1, 0x4c, 0xca, 0x5e, 0x87, 0xbe, 0xe4, 0x9f, 0xb0, + 0x5b, 0xb4, 0x3a, 0xef, 0xaf, 0xa3, 0x31, 0x44, 0x18, 0xeb, 0x8d, 0xc1, 0xf5, 0x25, 0x30, 0x26, + 0x9a, 0xdc, 0x1c, 0x90, 0x60, 0x30, 0x07, 0xe9, 0x93, 0xa9, 0xdc, 0xa2, 0xcd, 0xe1, 0x3b, 0x3a, + 0x75, 0x2c, 0xaa, 0x6a, 0x7f, 0x2f, 0xf1, 0xa6, 0xb4, 0x39, 0x7e, 0x20, 0x65, 0x3f, 0x25, 0x55, + 0x2a, 0xd2, 0xc1, 0x10, 0x98, 0x5f, 0x8f, 0x00, 0xa3, 0xc2, 0x90, 0xf9, 0x0b, 0xe6, 0xc0, 0x23, + 0x3e, 0x41, 0x02, 0x2c, 0x31, 0xca, 0x90, 0xb2, 0x9f, 0x91, 0x8e, 0xaa, 0xd5, 0x07, 0xfa, 0x7f, + 0x45, 0x09, 0x60, 0x3d, 0x8d, 0x01, 0x6e, 0x33, 0x85, 0x7a, 0x1e, 0x08, 0x10, 0xce, 0xb7, 0x48, + 0xd6, 0xd3, 0x31, 0x83, 0xe0, 0x10, 0x1c, 0xc2, 0x15, 0xc0, 0x9c, 0x5c, 0x08, 0xa8, 0x3c, 0x20, + 0x2d, 0x5d, 0xca, 0x81, 0x78, 0x15, 0x17, 0xde, 0x23, 0xed, 0x51, 0x81, 0x34, 0xab, 0x40, 0xbc, + 0x5f, 0x84, 0x81, 0xa3, 0x7d, 0x32, 0xaf, 0x0e, 0x1b, 0x98, 0x73, 0x2d, 0xb4, 0xdb, 0x85, 0xca, + 0xcb, 0x6a, 0x7d, 0x63, 0x9f, 0x94, 0x0f, 0x72, 0x79, 0x1c, 0x6c, 0xde, 0x92, 0x75, 0x09, 0x8e, + 0x3c, 0x08, 0x7f, 0x01, 0x6d, 0x50, 0x18, 0xe9, 0xc7, 0x21, 0x28, 0x14, 0x73, 0xd6, 0x1f, 0x73, + 0x52, 0x32, 0xb5, 0xb1, 0xdd, 0x14, 0x77, 0x73, 0x4e, 0xe0, 0x11, 0x25, 0x33, 0x1e, 0x23, 0xb7, + 0x2e, 0xb4, 0x87, 0x8d, 0x9a, 0x8c, 0x15, 0xc2, 0x61, 0x20, 0x42, 0x38, 0xdf, 0x8c, 0xa1, 0x11, + 0x84, 0xdd, 0xf9, 0xed, 0xa9, 0x4b, 0xb2, 0x13, 0xb8, 0xdd, 0xd5, 0x20, 0xe3, 0xbe, 0x70, 0x64, + 0x83, 0x5f, 0x3c, 0xbe, 0x20, 0xc4, 0x74, 0x9b, 0x64, 0xd2, 0x49, 0x56, 0x3d, 0x5d, 0x2b, 0xd2, + 0xcb, 0xfb, 0x71, 0x2e, 0x0f, 0xec, 0xc7, 0x99, 0xd6, 0x0c, 0xde, 0x72, 0x42, 0x40, 0x88, 0x0b, + 0x08, 0xb1, 0xca, 0x0c, 0xea, 0x3e, 0xc4, 0x3d, 0x1d, 0x6c, 0x01, 0x75, 0xcb, 0xf5, 0x12, 0x9d, + 0x8f, 0xc1, 0x06, 0x4e, 0x94, 0xf6, 0xdc, 0x64, 0x29, 0x45, 0x73, 0xcc, 0xca, 0x4f, 0x1e, 0x1a, + 0x39, 0xa5, 0x8a, 0x6a, 0x2a, 0xd8, 0xae, 0xaa, 0x0b, 0x5d, 0x27, 0xa3, 0x47, 0xfe, 0xf8, 0xf7, + 0x80, 0x8a, 0x99, 0x3a, 0x52, 0x66, 0xea, 0x48, 0x41, 0x57, 0x3a, 0x65, 0x57, 0x5c, 0xc8, 0x95, + 0x5a, 0xa4, 0xba, 0x52, 0xf7, 0x4b, 0x26, 0xad, 0xf4, 0x56, 0x2c, 0x5a, 0x8b, 0x8f, 0xe3, 0xd0, + 0x12, 0x3c, 0xaf, 0x21, 0x31, 0xd2, 0x5b, 0x09, 0x34, 0xc3, 0x40, 0x33, 0x74, 0x24, 0x07, 0x2c, + 0x87, 0x87, 0xd6, 0xe7, 0xde, 0xf4, 0x54, 0x1d, 0x47, 0x98, 0x6a, 0x77, 0x79, 0xa1, 0xfe, 0xfa, + 0xe4, 0x23, 0x1f, 0x42, 0x7f, 0x36, 0xda, 0x9f, 0x8d, 0xf6, 0x07, 0x9e, 0x88, 0x56, 0x19, 0x1f, + 0xea, 0x2f, 0x3b, 0xd8, 0xdf, 0x43, 0xe2, 0x91, 0x9b, 0x50, 0x91, 0x71, 0x26, 0xc9, 0x47, 0x10, + 0x7c, 0x9e, 0xf2, 0x7c, 0x2c, 0x15, 0x72, 0x18, 0xe4, 0x24, 0x30, 0xab, 0x43, 0xc6, 0xa0, 0xd6, + 0xe6, 0x99, 0x95, 0xf4, 0x89, 0xaa, 0x5f, 0xe6, 0x0f, 0x76, 0xb9, 0x7e, 0x58, 0x83, 0x96, 0x12, + 0xeb, 0x71, 0x62, 0x02, 0xea, 0xeb, 0xc8, 0xc0, 0x58, 0x5e, 0xcf, 0x55, 0xcf, 0x46, 0xb5, 0x11, + 0x40, 0x20, 0x62, 0x45, 0x0f, 0x18, 0x82, 0xd3, 0xc6, 0x13, 0x60, 0xdb, 0xad, 0x20, 0x4d, 0xe1, + 0x18, 0xb6, 0x75, 0x90, 0x96, 0x89, 0xe0, 0xa8, 0x40, 0x0c, 0xfb, 0x1f, 0x54, 0xd2, 0xf2, 0xbb, + 0xa4, 0x03, 0xc8, 0x70, 0x50, 0x19, 0x9b, 0x05, 0x04, 0xaa, 0x83, 0x9c, 0x51, 0xf6, 0x7e, 0xa5, + 0xfa, 0x08, 0x0d, 0xc4, 0x7a, 0x8d, 0x08, 0x87, 0x93, 0xfa, 0x71, 0x13, 0x40, 0xd0, 0x4f, 0x11, + 0x5a, 0xc0, 0xc6, 0xef, 0x03, 0xe1, 0x36, 0x75, 0xc1, 0xdc, 0xc9, 0xb7, 0xb1, 0x83, 0xc0, 0x73, + 0x6e, 0xdf, 0x2d, 0x98, 0x93, 0xf9, 0x8e, 0x07, 0xf9, 0x36, 0xc9, 0xd4, 0x1e, 0x0f, 0x46, 0xa0, + 0x0b, 0x7a, 0x49, 0xaa, 0xa7, 0xd2, 0xd4, 0x1e, 0x7f, 0x16, 0xe2, 0xb6, 0x94, 0x56, 0xe2, 0x8f, + 0x1f, 0xe0, 0xd2, 0x87, 0x48, 0xe5, 0x05, 0x1a, 0xeb, 0x79, 0x00, 0xb9, 0xbe, 0xd4, 0x99, 0x5a, + 0x21, 0x46, 0xe2, 0x13, 0xa4, 0x84, 0xb7, 0x51, 0x13, 0x20, 0xda, 0xbe, 0x8f, 0x2a, 0x75, 0x1c, + 0xc6, 0x98, 0x75, 0x52, 0x65, 0x57, 0x9e, 0x72, 0x3b, 0x39, 0x44, 0x82, 0x80, 0x70, 0xda, 0xac, + 0xcc, 0xa7, 0xce, 0xb1, 0x8e, 0x3b, 0x18, 0xb9, 0x2c, 0x1a, 0xb7, 0xcb, 0xdc, 0xab, 0xd0, 0x68, + 0xf4, 0x8b, 0x4d, 0x3a, 0x40, 0x90, 0x08, 0x6d, 0xe0, 0xd8, 0x46, 0x32, 0xc0, 0xd0, 0x30, 0x67, + 0x09, 0x7a, 0xfb, 0x0f, 0x20, 0x3b, 0x4e, 0x90, 0xc1, 0x94, 0xc9, 0xdb, 0x74, 0x69, 0x62, 0xbd, + 0x2e, 0xa5, 0x59, 0xb8, 0x49, 0xbc, 0x3e, 0x2d, 0x2e, 0x85, 0x8c, 0x45, 0x23, 0xa0, 0x5b, 0x21, + 0x65, 0xfe, 0x78, 0x20, 0x38, 0x26, 0xa1, 0xab, 0xff, 0x4b, 0x1c, 0x90, 0x9f, 0x3b, 0xb8, 0xea, + 0xc7, 0x77, 0xb8, 0x7d, 0x67, 0xd8, 0x56, 0xb4, 0x86, 0xe0, 0x1c, 0xe4, 0xa0, 0x6c, 0xd6, 0x29, + 0xa6, 0x49, 0x41, 0x06, 0xaa, 0xbd, 0x3b, 0x7f, 0xd2, 0xf9, 0x17, 0x46, 0xdd, 0x08, 0x68, 0x65, + 0xd4, 0x8e, 0x96, 0x4c, 0x06, 0x7a, 0x88, 0x9f, 0x31, 0x15, 0x5c, 0xb0, 0xbb, 0x6f, 0xc0, 0xee, + 0x54, 0xfa, 0x7d, 0x63, 0xdd, 0x27, 0x10, 0x6e, 0x35, 0xee, 0xa7, 0xc8, 0x9a, 0x15, 0xd2, 0xaa, + 0x57, 0x6e, 0x26, 0x9d, 0x92, 0xac, 0xd7, 0xc4, 0x2b, 0x80, 0xed, 0xaa, 0x57, 0x06, 0x52, 0x4e, + 0xe1, 0x9b, 0xf8, 0x13, 0x5a, 0xfc, 0x4a, 0xf8, 0xba, 0x3b, 0x52, 0x65, 0x5c, 0xe0, 0xe0, 0x3a, + 0x2a, 0xd3, 0xfb, 0xe6, 0xa9, 0x93, 0xc1, 0x2b, 0x98, 0x0c, 0x59, 0x95, 0xde, 0xfe, 0x2f, 0xd8, + 0x8b, 0xe1, 0x7c, 0xc7, 0x44, 0x01, 0x9c, 0x9e, 0x66, 0x29, 0xff, 0x30, 0x7b, 0x19, 0x66, 0x2d, + 0xa9, 0xd2, 0x93, 0x67, 0x03, 0x77, 0x87, 0x8f, 0x0b, 0x24, 0x2b, 0xbf, 0xbc, 0x47, 0x9d, 0x2a, + 0xe3, 0x58, 0xe0, 0x48, 0xcb, 0x44, 0x2b, 0x94, 0xea, 0x52, 0x6e, 0x91, 0x16, 0xe0, 0x63, 0x3c, + 0x30, 0x33, 0x8e, 0xdb, 0xad, 0x50, 0x5b, 0xbe, 0x54, 0x8d, 0x3a, 0x17, 0xe6, 0xd0, 0xb0, 0xe5, + 0xf7, 0x66, 0x1a, 0x9a, 0xbd, 0x05, 0x82, 0x68, 0xbf, 0x03, 0xd4, 0xf5, 0xf5, 0xd8, 0x63, 0x20, + 0xcb, 0xe7, 0x03, 0x69, 0x03, 0x63, 0x2d, 0x59, 0x61, 0x26, 0x38, 0xad, 0xe8, 0x71, 0xa6, 0xf1, + 0x1a, 0x3d, 0xe0, 0xb7, 0x87, 0x83, 0xdd, 0x00, 0xf5, 0x1e, 0x76, 0x89, 0x96, 0xa3, 0x2c, 0x9d, + 0x21, 0x31, 0xa0, 0x77, 0xf2, 0xef, 0xbf, 0x43, 0xbd, 0xc3, 0x6d, 0x6c, 0xb3, 0x39, 0x27, 0x57, + 0xd1, 0xdd, 0xa3, 0x7a, 0x60, 0xee, 0xcf, 0x21, 0xbf, 0x34, 0xdc, 0x3e, 0x08, 0x90, 0xcd, 0xca, + 0xd2, 0x98, 0x50, 0xf0, 0xb4, 0x54, 0x76, 0x0f, 0x8d, 0x2c, 0x99, 0x79, 0xb7, 0x64, 0xa6, 0xec, + 0xde, 0x87, 0x25, 0x11, 0xf6, 0x13, 0xab, 0xb1, 0x44, 0x7b, 0xb7, 0x04, 0xfc, 0xe7, 0xec, 0xce, + 0x17, 0x80, 0x99, 0xb5, 0xef, 0x1c, 0xc2, 0x65, 0x9c, 0x03, 0xa7, 0xea, 0x06, 0x70, 0x61, 0x23, + 0x90, 0xbd, 0xf8, 0xed, 0x16, 0x70, 0xcf, 0x9d, 0xda, 0x54, 0xe1, 0xef, 0x9d, 0x3f, 0x42, 0x39, + 0x31, 0x01, 0x67, 0xe5, 0x83, 0x74, 0xad, 0xa7, 0x95, 0x56, 0x2a, 0x5e, 0x52, 0xd3, 0x8c, 0x55, + 0xa2, 0x45, 0x4f, 0x98, 0xd0, 0xd3, 0xb9, 0x80, 0xa5, 0x4b, 0xa1, 0x47, 0xbe, 0xa3, 0x8b, 0x6f, + 0xde, 0xf6, 0x08, 0x39, 0x33, 0x0c, 0xd7, 0xe3, 0xc8, 0xa5, 0x9f, 0x91, 0xca, 0x96, 0x7e, 0x78, + 0xbd, 0x06, 0xc5, 0xc7, 0xa0, 0x18, 0xc2, 0xcb, 0x48, 0xc9, 0x7d, 0x9a, 0x82, 0x3a, 0xf2, 0x09, + 0xfd, 0xb9, 0x84, 0x0b, 0x18, 0x07, 0x8f, 0xd4, 0x63, 0x69, 0x40, 0x7a, 0xab, 0x05, 0x81, 0x54, + 0x76, 0x80, 0x97, 0xcd, 0x65, 0x0e, 0xd6, 0x1e, 0x39, 0x4c, 0x51, 0x83, 0x3a, 0x0a, 0xb7, 0x6f, + 0x30, 0xbc, 0xb2, 0x0b, 0x78, 0xcf, 0x0e, 0x26, 0xe1, 0xbe, 0x8a, 0xe0, 0x5f, 0x76, 0x93, 0x63, + 0x98, 0x6d, 0x51, 0x4d, 0x59, 0x1a, 0x1d, 0x90, 0xd5, 0x37, 0x7e, 0xd9, 0x4d, 0xf0, 0xed, 0xb6, + 0xe9, 0x21, 0xad, 0x57, 0x77, 0x62, 0xd0, 0x41, 0xf0, 0x4d, 0x80, 0x34, 0x6e, 0xc9, 0xec, 0x87, + 0x09, 0xdc, 0x2f, 0xf1, 0xed, 0xa0, 0x62, 0x38, 0xcb, 0x58, 0xbb, 0x8a, 0xc9, 0x6a, 0x5d, 0xcd, + 0xd3, 0xe3, 0x8b, 0x89, 0x4d, 0x5f, 0xb3, 0x6b, 0x82, 0xe4, 0x6e, 0xc6, 0x9e, 0xb3, 0x62, 0xc1, + 0xb8, 0x93, 0xa7, 0xe3, 0x24, 0xb9, 0x0d, 0x93, 0xab, 0x13, 0x89, 0x2d, 0x41, 0xe2, 0xdb, 0x8a, + 0x49, 0xd6, 0x6c, 0x6e, 0xdf, 0x6d, 0xf6, 0x12, 0xd9, 0x35, 0xc7, 0x78, 0x15, 0x38, 0x87, 0x08, + 0xb4, 0xb8, 0xc0, 0x5d, 0x27, 0x59, 0xc9, 0x4e, 0xbd, 0x9c, 0xff, 0xfb, 0x62, 0xf2, 0xf8, 0x64, + 0x6f, 0xa7, 0x1e, 0x7e, 0x62, 0x7d, 0x61, 0x6c, 0x13, 0xd9, 0x65, 0x30, 0x06, 0x64, 0xfe, 0x34, + 0x46, 0x45, 0x60, 0x85, 0x2e, 0xab, 0x61, 0x9d, 0xdb, 0x53, 0x47, 0x97, 0x6b, 0x81, 0xf7, 0xa7, + 0x49, 0x16, 0x04, 0x8b, 0x55, 0xc7, 0x91, 0xeb, 0xa3, 0x3c, 0xe3, 0x6a, 0x54, 0x65, 0x94, 0x96, + 0xb7, 0x15, 0xe4, 0xb6, 0xf1, 0x2a, 0x2e, 0xb4, 0xd5, 0x60, 0xa6, 0x49, 0x67, 0x0c, 0xac, 0x71, + 0xed, 0x4c, 0x61, 0xe7, 0xc9, 0x2f, 0xb1, 0xce, 0x3e, 0x89, 0xff, 0x05, 0x98, 0x27, 0x98, 0xd6, + 0x07, 0x0c, 0x42, 0xac, 0xc4, 0x1f, 0x96, 0xdf, 0x52, 0xd7, 0xb1, 0xd3, 0x27, 0x7b, 0x15, 0xc0, + 0x23, 0x3d, 0x56, 0xd6, 0xa4, 0x18, 0xfb, 0x3e, 0xbd, 0x8d, 0x5b, 0x4d, 0x07, 0x5e, 0x8d, 0x8b, + 0x40, 0x14, 0x20, 0x66, 0x8c, 0x76, 0x9f, 0x70, 0x6e, 0x58, 0x9d, 0x21, 0xf8, 0x7c, 0x3b, 0x49, + 0x77, 0xff, 0xe5, 0x1c, 0xb3, 0xec, 0x76, 0xa0, 0x95, 0xc7, 0x35, 0x35, 0xdd, 0x22, 0x2a, 0x1d, + 0x8d, 0xd5, 0x53, 0x11, 0x14, 0x03, 0x38, 0x00, 0x9d, 0x82, 0xe5, 0x72, 0xfe, 0x69, 0x8b, 0x12, + 0x13, 0x1a, 0x87, 0xba, 0x7c, 0x9a, 0xd4, 0x9f, 0x5d, 0x6a, 0xb0, 0xc8, 0x1f, 0x63, 0x6d, 0x9b, + 0x72, 0xe6, 0x11, 0xd5, 0x73, 0xed, 0x01, 0x4c, 0x7d, 0xbb, 0xfb, 0xaf, 0xdb, 0xee, 0x82, 0xbe, + 0xa8, 0xfc, 0xf1, 0x11, 0x0c, 0x71, 0x47, 0xc3, 0x0e, 0x01, 0xe6, 0xc1, 0x40, 0xd5, 0xa9, 0x5e, + 0xa3, 0x3a, 0xda, 0x9f, 0x33, 0x34, 0x7e, 0x7c, 0x64, 0x4e, 0xd0, 0xd7, 0x2a, 0x5d, 0xae, 0x3c, + 0xa8, 0xbe, 0x43, 0x80, 0x64, 0x90, 0x85, 0xb7, 0x0f, 0x8d, 0x43, 0x3d, 0x6a, 0xea, 0xfd, 0x80, + 0x3b, 0x68, 0xfd, 0x92, 0x98, 0x17, 0x08, 0x13, 0xb9, 0x83, 0xa6, 0x76, 0xef, 0x0d, 0x7d, 0x14, + 0x38, 0xe8, 0x7e, 0xc8, 0x20, 0x4d, 0xbe, 0x08, 0x08, 0x51, 0xac, 0x7e, 0x70, 0xed, 0x65, 0xfe, + 0x6d, 0xee, 0x60, 0xb9, 0x4e, 0xce, 0xc4, 0x48, 0xbc, 0xbf, 0x8f, 0x64, 0x2f, 0x25, 0x6b, 0x16, + 0x41, 0x9c, 0xee, 0xc9, 0xa4, 0xe3, 0xf3, 0x9b, 0x95, 0x1b, 0xe1, 0x6a, 0x47, 0xd9, 0xa9, 0xe4, + 0x45, 0x7d, 0x53, 0x46, 0xec, 0x0f, 0xee, 0x85, 0x48, 0x35, 0x23, 0x6e, 0x0d, 0xfc, 0x48, 0xd9, + 0x8b, 0x48, 0x46, 0x42, 0x53, 0x86, 0x81, 0x51, 0x03, 0x16, 0xdc, 0x58, 0x69, 0xab, 0x3a, 0x5e, + 0x1d, 0x5a, 0x74, 0x32, 0x5e, 0xf5, 0x7d, 0x1b, 0xe2, 0xdc, 0x22, 0xd4, 0x95, 0x8b, 0xe4, 0x14, + 0x77, 0x20, 0x6d, 0x3c, 0x77, 0x70, 0x87, 0x0e, 0x9c, 0x12, 0xd9, 0x7d, 0x18, 0x83, 0xda, 0x08, + 0x1a, 0xa7, 0x98, 0x15, 0xef, 0xc2, 0xe0, 0x2a, 0x2e, 0xa9, 0xec, 0x72, 0x96, 0x72, 0x07, 0x6d, + 0x93, 0xc5, 0x17, 0x35, 0x06, 0x21, 0x0a, 0x2c, 0x6f, 0xac, 0xb7, 0x5d, 0x1f, 0x55, 0x0f, 0x9e, + 0x06, 0xb9, 0x6c, 0x56, 0xcc, 0xe1, 0xc1, 0xe9, 0x8c, 0xab, 0x6e, 0x46, 0xab, 0xd0, 0x24, 0x09, + 0x17, 0x20, 0xcc, 0xe4, 0xf6, 0x09, 0x5d, 0x36, 0xc5, 0xa0, 0x06, 0xc7, 0x10, 0xa8, 0x0f, 0x42, + 0x2c, 0x60, 0xb3, 0x58, 0x40, 0x06, 0xcc, 0xca, 0x64, 0x1a, 0xae, 0x83, 0x1c, 0x5c, 0x93, 0x35, + 0x6e, 0x44, 0x16, 0x9c, 0xfe, 0x8f, 0x7e, 0xa0, 0x2e, 0x65, 0x64, 0x71, 0x07, 0x33, 0x66, 0x53, + 0xb5, 0x1c, 0x13, 0xa0, 0x7b, 0xa3, 0xd0, 0x0b, 0x7f, 0x8d, 0x34, 0x72, 0xfb, 0xfa, 0x6d, 0x4a, + 0x2b, 0xad, 0xa4, 0xe1, 0x0e, 0x5a, 0x00, 0x61, 0xcb, 0x1c, 0xee, 0xe0, 0xe3, 0xb3, 0x21, 0x0e, + 0x04, 0x77, 0x29, 0x27, 0x2f, 0x17, 0x21, 0x83, 0xd3, 0x26, 0xeb, 0xd5, 0x18, 0x6e, 0xc8, 0xe0, + 0x18, 0x6f, 0xec, 0x5b, 0x2d, 0xc1, 0xcc, 0x67, 0xf2, 0x77, 0x4e, 0x0b, 0xa3, 0xcb, 0xd0, 0x72, + 0x0e, 0x2b, 0xef, 0x18, 0x8f, 0x4e, 0x51, 0x17, 0x06, 0x47, 0x42, 0x87, 0xf7, 0xcb, 0x88, 0x5a, + 0x8d, 0x11, 0xd7, 0x1d, 0x6e, 0xe1, 0x54, 0x11, 0x6b, 0x04, 0x1f, 0x51, 0xac, 0xd4, 0x31, 0xb5, + 0xab, 0x8c, 0x63, 0xb9, 0xea, 0xdf, 0x42, 0x9e, 0xeb, 0x16, 0xc7, 0xb9, 0x61, 0x22, 0x67, 0x3e, + 0x4c, 0x75, 0x4e, 0x51, 0x89, 0x63, 0x50, 0x29, 0x65, 0x56, 0xfe, 0xe3, 0xe1, 0xd0, 0xe6, 0x42, + 0x2d, 0x93, 0x38, 0x9d, 0x3b, 0xd0, 0x2c, 0xc7, 0xae, 0x90, 0x33, 0x7f, 0xd2, 0xbb, 0x2c, 0x1c, + 0x8d, 0xcc, 0x2b, 0xbb, 0x90, 0xc6, 0x95, 0xed, 0x40, 0x11, 0xde, 0x2f, 0x67, 0x26, 0x8f, 0x05, + 0x67, 0x4f, 0x8e, 0xfd, 0x09, 0xa9, 0x3c, 0x2d, 0xbf, 0xba, 0x0c, 0x01, 0xc8, 0x6f, 0xde, 0x83, + 0x3f, 0x9f, 0xde, 0xa6, 0xa1, 0x8b, 0x52, 0x9b, 0xb9, 0x3e, 0xba, 0x26, 0x73, 0xf2, 0x40, 0x86, + 0xf0, 0x77, 0x5c, 0xf8, 0x6e, 0xaf, 0xd5, 0xe4, 0xd5, 0x64, 0xc6, 0x44, 0xa4, 0x8b, 0x83, 0x91, + 0x42, 0x2f, 0x38, 0x67, 0xb5, 0x69, 0x09, 0xe0, 0x1d, 0xd6, 0x54, 0xdf, 0xd3, 0x04, 0x8d, 0x6a, + 0xd3, 0xa6, 0xc1, 0x5b, 0x33, 0xbc, 0xb9, 0xcf, 0xc1, 0x68, 0x38, 0x37, 0x4a, 0x7b, 0x1d, 0xf6, + 0xeb, 0x3a, 0x1c, 0x81, 0x50, 0x0d, 0x82, 0x56, 0xf4, 0x04, 0x2a, 0xba, 0x8d, 0x9e, 0xe5, 0xb2, + 0x8c, 0x19, 0x8d, 0x99, 0x5a, 0x96, 0x19, 0x19, 0x83, 0x7d, 0xa2, 0xc6, 0x60, 0xf5, 0xe0, 0x26, + 0xe5, 0xd0, 0x08, 0x0c, 0x59, 0x58, 0x48, 0x27, 0xe7, 0x96, 0x5a, 0x6d, 0x9f, 0x57, 0x2b, 0x59, + 0x61, 0xbe, 0xec, 0xe0, 0xdc, 0xff, 0x01, 0xa3, 0xaf, 0xfb, 0x7b, 0x00, 0x41, 0x44, 0x9c, 0x36, + 0xa4, 0x0a, 0x03, 0x12, 0xaf, 0xab, 0xc5, 0xb5, 0xca, 0xf5, 0xc6, 0xab, 0x7f, 0x60, 0x61, 0xfa, + 0x37, 0xf6, 0x65, 0x2d, 0x9d, 0xeb, 0x7c, 0x48, 0xbc, 0xad, 0xe5, 0xde, 0xf0, 0x8a, 0xb7, 0xa3, + 0xb9, 0x57, 0x30, 0x1a, 0x9e, 0x69, 0x6a, 0x17, 0x5e, 0xe4, 0x8e, 0x7a, 0xcc, 0x4a, 0x76, 0x34, + 0x65, 0x5b, 0x4d, 0xe6, 0x54, 0x6f, 0x06, 0xb6, 0xd5, 0x24, 0x67, 0x41, 0xc8, 0x75, 0xda, 0x37, + 0xbd, 0x8f, 0x6f, 0x67, 0x81, 0x2d, 0xce, 0x17, 0xd4, 0xdc, 0x4f, 0xb5, 0xd4, 0x16, 0xb6, 0x33, + 0xea, 0x92, 0xe3, 0x6f, 0x4b, 0xc7, 0xca, 0xbc, 0xd7, 0x2c, 0xe5, 0xb7, 0x59, 0x94, 0x3b, 0xd1, + 0xc1, 0xb9, 0x20, 0x88, 0x54, 0xf5, 0xaf, 0xa8, 0x8c, 0xa3, 0x6c, 0xa8, 0x2c, 0xf6, 0x25, 0xb8, + 0x6e, 0x69, 0x71, 0xa7, 0x81, 0x96, 0x0b, 0xe3, 0x7d, 0x41, 0xd6, 0xab, 0xe9, 0x2c, 0x90, 0x35, + 0x6e, 0x5f, 0x83, 0x57, 0x89, 0x10, 0xeb, 0x0d, 0x62, 0x93, 0x21, 0xa5, 0x91, 0xdb, 0x3d, 0x08, + 0x16, 0xcb, 0x17, 0x01, 0xb5, 0x7c, 0x57, 0x41, 0x50, 0xb8, 0x7d, 0xf9, 0x17, 0x2c, 0x39, 0xca, + 0xfd, 0xb3, 0x55, 0x31, 0x0c, 0x87, 0x2c, 0xf4, 0xc3, 0x16, 0x85, 0x94, 0xa7, 0x54, 0xa7, 0x58, + 0x66, 0x87, 0x16, 0x90, 0xc7, 0x42, 0x80, 0x60, 0x56, 0x6a, 0xe7, 0x53, 0x9c, 0xea, 0xc6, 0xe2, + 0xa2, 0xc7, 0xce, 0x31, 0x48, 0xf2, 0x46, 0x90, 0x5a, 0x66, 0xb9, 0xd0, 0x8d, 0xda, 0xb7, 0xc8, + 0xd8, 0xd7, 0xe9, 0xc2, 0xf9, 0xcc, 0x60, 0x41, 0xcf, 0xf0, 0x29, 0xb5, 0x36, 0x64, 0xda, 0x71, + 0xbb, 0xa1, 0x12, 0x44, 0xe2, 0x51, 0x43, 0xa9, 0xc1, 0x8c, 0x65, 0xa9, 0x50, 0x46, 0x6e, 0xa9, + 0xa5, 0x8e, 0xc0, 0x88, 0x7d, 0x67, 0xf4, 0xd4, 0x77, 0x68, 0x8c, 0x1e, 0x31, 0xa0, 0x3b, 0xf4, + 0x2d, 0x87, 0xcb, 0x31, 0xcd, 0x62, 0x40, 0x7f, 0xf4, 0x5b, 0xdc, 0x99, 0xe3, 0xfd, 0x51, 0x67, + 0xc4, 0x80, 0xe1, 0xd3, 0x6f, 0xc1, 0x66, 0x72, 0xfc, 0x75, 0x71, 0x30, 0xac, 0x62, 0x73, 0xca, + 0xf9, 0x8a, 0x12, 0x99, 0xf7, 0x13, 0xbd, 0xb1, 0xcf, 0x48, 0x57, 0x84, 0x20, 0x34, 0x46, 0x8d, + 0xfb, 0x90, 0xda, 0x42, 0x08, 0xa4, 0xfd, 0xd9, 0xe0, 0xcd, 0x63, 0x55, 0x4d, 0xca, 0x95, 0xad, + 0x37, 0x6c, 0xca, 0x4b, 0x6a, 0x14, 0x0b, 0x1e, 0x0c, 0xaf, 0xe0, 0x0a, 0x54, 0x40, 0xce, 0xf7, + 0x3b, 0xa7, 0x1b, 0xfb, 0x88, 0xa9, 0x03, 0x2a, 0x93, 0xd8, 0x3f, 0x00, 0x04, 0x8b, 0x52, 0x42, + 0x4d, 0x7a, 0x07, 0x54, 0xcc, 0x4a, 0xe9, 0x17, 0xbe, 0xa4, 0xa3, 0x23, 0xcd, 0x23, 0xb6, 0x87, + 0xd1, 0x7b, 0x5f, 0xae, 0x97, 0x72, 0x52, 0xef, 0xba, 0xf7, 0x01, 0x41, 0x8f, 0xfe, 0xf7, 0x3c, + 0x6a, 0x2b, 0x63, 0x47, 0xf9, 0xf8, 0x59, 0x99, 0x34, 0x06, 0xde, 0x9a, 0xaa, 0xd4, 0xa9, 0x8b, + 0xf8, 0xa5, 0xcb, 0x6d, 0xca, 0x47, 0xf7, 0x8f, 0xf0, 0xea, 0xe9, 0xe0, 0x0d, 0xc4, 0x7a, 0x01, + 0x0f, 0x9b, 0xf0, 0xb1, 0x63, 0xf9, 0x38, 0xae, 0xfa, 0x7f, 0x18, 0xaa, 0xc2, 0xdc, 0xc1, 0x34, + 0x1d, 0x77, 0x60, 0xc5, 0x78, 0x08, 0x5d, 0x88, 0xa9, 0x4d, 0xf5, 0x7a, 0xaf, 0x01, 0xb6, 0xe1, + 0x26, 0x1d, 0x31, 0x29, 0x13, 0xad, 0x7a, 0x98, 0x1b, 0x8c, 0x1e, 0x33, 0x38, 0x74, 0xb6, 0xdc, + 0x1c, 0xc5, 0x73, 0x4d, 0xf5, 0x71, 0x61, 0x2a, 0x3d, 0x2f, 0x55, 0xc6, 0x3e, 0x58, 0x09, 0xc1, + 0x50, 0xdc, 0x14, 0x13, 0xc8, 0xc2, 0x75, 0x98, 0x5e, 0xc1, 0x15, 0xbc, 0x02, 0xc1, 0x60, 0x52, + 0x03, 0xc9, 0x47, 0xcf, 0x34, 0xbe, 0x05, 0xc2, 0xb4, 0xa4, 0xeb, 0x74, 0x97, 0x32, 0xbe, 0x21, + 0xa5, 0x9f, 0x34, 0xc7, 0xb7, 0x71, 0xe9, 0x97, 0xb9, 0xf4, 0x7e, 0x0c, 0x9b, 0x20, 0x36, 0xd6, + 0xd5, 0x88, 0xde, 0x21, 0x5c, 0x44, 0x3a, 0x90, 0x0e, 0xfd, 0x7b, 0x8d, 0x27, 0xc2, 0xd3, 0x0d, + 0xdc, 0xeb, 0x5e, 0xee, 0x60, 0x2e, 0x98, 0xa3, 0x93, 0xfd, 0x9f, 0xb3, 0xad, 0xe1, 0xbc, 0x32, + 0x11, 0x58, 0x66, 0xd5, 0x4a, 0x95, 0x1d, 0xec, 0xa0, 0xc5, 0x96, 0x63, 0xce, 0xc5, 0x1d, 0x83, + 0x64, 0xe8, 0x5b, 0xe9, 0x1d, 0x8b, 0x93, 0xe5, 0x35, 0x4a, 0xc7, 0x38, 0x5c, 0x8f, 0x8a, 0x8b, + 0xb9, 0x82, 0xbe, 0x5a, 0xbc, 0x9f, 0xdb, 0x8d, 0xdb, 0xae, 0xe2, 0x71, 0xc3, 0x88, 0xc9, 0xd5, + 0x2c, 0x55, 0x6a, 0xa5, 0x34, 0x0d, 0x1e, 0xfa, 0xb8, 0x5f, 0x1c, 0xd0, 0x0b, 0x99, 0x10, 0xef, + 0x8e, 0xe1, 0x0e, 0x3e, 0x0f, 0x3d, 0x3d, 0x9f, 0x20, 0xc7, 0xda, 0xcc, 0xa5, 0x61, 0xe6, 0xdc, + 0xbc, 0x80, 0x51, 0xf9, 0xc5, 0x58, 0x24, 0x5c, 0x82, 0xef, 0x79, 0x4a, 0x99, 0x7d, 0x69, 0x09, + 0xb2, 0xe6, 0x35, 0xe3, 0xb9, 0x5c, 0x0c, 0xe3, 0xb0, 0xb8, 0x72, 0xac, 0xba, 0xf8, 0xb2, 0x31, + 0x9c, 0xf3, 0x3d, 0x8e, 0x30, 0x64, 0xa1, 0xa7, 0x18, 0x4f, 0x76, 0x84, 0x60, 0x91, 0x4b, 0xe4, + 0x7c, 0xab, 0x8f, 0x3d, 0xcf, 0xf6, 0x22, 0x48, 0x0b, 0x14, 0xdb, 0xa0, 0x59, 0xd6, 0xd8, 0x90, + 0x1b, 0x4c, 0xf7, 0x94, 0x66, 0x05, 0x40, 0xf8, 0xc8, 0x60, 0x5f, 0x3d, 0xcb, 0xe1, 0x1e, 0x8d, + 0x96, 0xb0, 0x20, 0x0b, 0x21, 0x6c, 0x51, 0x82, 0xeb, 0xff, 0x4e, 0x97, 0x0c, 0xc0, 0x57, 0x0b, + 0xcb, 0x6f, 0xc8, 0xef, 0x6c, 0xed, 0xa1, 0x42, 0x9c, 0xdf, 0xf9, 0xa3, 0x9e, 0x90, 0x34, 0x4b, + 0xf9, 0x3a, 0x8b, 0x22, 0x8c, 0x09, 0xba, 0xfa, 0x62, 0x63, 0x98, 0x4d, 0x09, 0x9b, 0x15, 0x54, + 0x28, 0xd7, 0x92, 0x79, 0x82, 0xc6, 0x92, 0xe7, 0xd3, 0x36, 0x8e, 0x99, 0x47, 0x06, 0x52, 0x2d, + 0x66, 0xe5, 0x91, 0x48, 0xd5, 0x21, 0xce, 0xd7, 0xba, 0x5e, 0x1c, 0xc7, 0x38, 0x63, 0xf2, 0xec, + 0xb2, 0x89, 0x65, 0x2c, 0xca, 0x61, 0x3a, 0x03, 0xe8, 0x7c, 0xc9, 0x79, 0x16, 0x65, 0xaf, 0x42, + 0xd7, 0x1f, 0xc0, 0x4f, 0x4b, 0x80, 0xd4, 0x0f, 0xc3, 0x82, 0xd3, 0xbd, 0x30, 0x1e, 0x52, 0x4f, + 0xf4, 0x07, 0xcb, 0x9c, 0x63, 0xc9, 0x76, 0x2d, 0x29, 0x57, 0xd7, 0xb9, 0x8d, 0x1e, 0x5f, 0x3f, + 0x15, 0x44, 0x41, 0xeb, 0x7a, 0x94, 0x71, 0x4e, 0x72, 0x81, 0x89, 0x16, 0xee, 0x0d, 0x6c, 0x4d, + 0x08, 0x6c, 0xd5, 0x2b, 0x0f, 0x26, 0xaa, 0xaa, 0x3f, 0xc6, 0x16, 0xb0, 0xc5, 0x01, 0x5a, 0x81, + 0xad, 0xba, 0xc0, 0x56, 0xad, 0x12, 0xab, 0x66, 0x97, 0x26, 0xdb, 0x94, 0xa8, 0xc4, 0x11, 0x32, + 0x4a, 0x57, 0x04, 0x19, 0xe7, 0xbd, 0x92, 0x49, 0x1f, 0xbe, 0x1c, 0x64, 0x3d, 0x2e, 0x07, 0xe5, + 0x7d, 0xab, 0xba, 0x67, 0x05, 0x34, 0x08, 0x3c, 0x13, 0x0b, 0xb5, 0x40, 0x14, 0xcd, 0xea, 0xf2, + 0x8b, 0x12, 0x41, 0x55, 0x41, 0x3f, 0xf2, 0x40, 0x17, 0xaf, 0x03, 0x2e, 0x8b, 0x95, 0xb1, 0x0c, + 0xf7, 0x56, 0xc3, 0xcc, 0x7c, 0xbd, 0xeb, 0x31, 0xc6, 0x99, 0xe7, 0x7a, 0x09, 0x66, 0xf2, 0x6d, + 0x7a, 0xc1, 0x68, 0x3c, 0xf1, 0x09, 0x52, 0x3d, 0x3c, 0x2f, 0x41, 0x7a, 0xc9, 0x10, 0x73, 0xb6, + 0xea, 0x73, 0xc6, 0x1f, 0x08, 0xe4, 0xe4, 0x94, 0xb2, 0x39, 0xe6, 0xbc, 0xdc, 0x1c, 0x9b, 0x72, + 0x2f, 0x5d, 0x65, 0x4f, 0x04, 0x3c, 0x1a, 0x53, 0x59, 0x16, 0x14, 0xab, 0xfa, 0x2a, 0x57, 0x3d, + 0x15, 0xe7, 0x9c, 0x87, 0xb5, 0x60, 0xe4, 0x9b, 0x22, 0x74, 0x31, 0xf4, 0x18, 0x11, 0xd3, 0x49, + 0xa7, 0xa3, 0x03, 0xa7, 0x72, 0xe8, 0x1a, 0xb5, 0x39, 0xb0, 0x2d, 0x41, 0x39, 0x74, 0x1f, 0xc5, + 0x85, 0x34, 0x56, 0x5f, 0x75, 0x4e, 0x91, 0x1e, 0x95, 0xb2, 0x34, 0xef, 0x63, 0x6d, 0xb2, 0x0c, + 0x5b, 0x02, 0x09, 0x1f, 0x3a, 0x8a, 0x2f, 0xbe, 0x30, 0xd2, 0x6f, 0xf4, 0x00, 0x0f, 0x02, 0x0e, + 0x43, 0xc0, 0x91, 0x60, 0x36, 0xe7, 0x59, 0x02, 0x96, 0x58, 0x10, 0x0b, 0xf8, 0x41, 0x0a, 0x81, + 0x07, 0x52, 0xdc, 0x14, 0xce, 0xb2, 0x9d, 0xbf, 0x66, 0xf0, 0xcc, 0x04, 0x40, 0x57, 0xe6, 0xdd, + 0x17, 0x5a, 0xc1, 0x41, 0x25, 0x78, 0x22, 0x41, 0x4a, 0x37, 0x90, 0xcb, 0x51, 0x5e, 0xa7, 0x23, + 0x78, 0x3e, 0x8c, 0x2e, 0x85, 0xe9, 0x21, 0x7e, 0x4e, 0xea, 0x85, 0x29, 0x2f, 0x7e, 0xe0, 0x10, + 0xa6, 0x52, 0x4e, 0x71, 0x19, 0x97, 0x61, 0xf6, 0xe1, 0x2f, 0xe7, 0x01, 0x61, 0x02, 0x82, 0x1f, + 0x94, 0x46, 0x1b, 0x30, 0x63, 0x4f, 0xe1, 0x74, 0x2c, 0x64, 0x60, 0x22, 0x1d, 0x0d, 0x6e, 0x1d, + 0x40, 0x98, 0x66, 0x85, 0x12, 0xba, 0xb8, 0xb0, 0x2e, 0x41, 0x4a, 0x35, 0x80, 0xdb, 0x97, 0x72, + 0x25, 0xbe, 0x89, 0x5c, 0xa4, 0xb0, 0xe4, 0xa5, 0xd1, 0x04, 0x5d, 0x6f, 0x6d, 0xc5, 0x3b, 0x14, + 0x23, 0x5c, 0x92, 0xcf, 0x99, 0x49, 0xf9, 0x46, 0xc7, 0x84, 0xeb, 0x14, 0xba, 0x51, 0x4e, 0x6c, + 0x62, 0x14, 0x2e, 0xe0, 0x41, 0x88, 0x21, 0x0b, 0xe7, 0xf2, 0x4a, 0x23, 0xf2, 0xec, 0xb8, 0x43, + 0x6e, 0xb3, 0x28, 0x19, 0x5a, 0xaa, 0x02, 0x8d, 0x59, 0x11, 0x8c, 0x7d, 0x2d, 0x44, 0x49, 0x36, + 0xe5, 0xbf, 0xc3, 0xef, 0x7a, 0x94, 0x1e, 0xdc, 0x36, 0xd0, 0x29, 0xa9, 0x33, 0x43, 0xc3, 0x25, + 0x6d, 0xd2, 0x54, 0x3d, 0x12, 0xef, 0xaa, 0x73, 0x5c, 0x4a, 0x38, 0x57, 0xfd, 0x6f, 0x68, 0xae, + 0x9e, 0xd4, 0xf9, 0xbe, 0x2d, 0xd5, 0x2b, 0x93, 0x83, 0xb5, 0x1a, 0xd0, 0x70, 0x86, 0x1f, 0xa5, + 0xe7, 0x0c, 0x02, 0x79, 0x76, 0x5c, 0x71, 0xcf, 0xb3, 0xc9, 0xf2, 0xf9, 0x3e, 0xe0, 0xab, 0x59, + 0x39, 0x3f, 0x26, 0xb8, 0xdc, 0xea, 0xc6, 0x0c, 0x71, 0x80, 0x75, 0x4e, 0x5a, 0x16, 0xa0, 0x5b, + 0xd9, 0xef, 0x40, 0x67, 0x55, 0x8d, 0x58, 0x1d, 0x00, 0xf8, 0x1a, 0x25, 0xf7, 0x0e, 0x90, 0x6e, + 0x92, 0xa1, 0x35, 0x2b, 0x9e, 0x19, 0x2a, 0xe4, 0x0c, 0x8d, 0x24, 0x3f, 0x0f, 0x99, 0xde, 0x1b, + 0x63, 0x41, 0xf7, 0x03, 0x0e, 0x6d, 0x6e, 0x0e, 0x9d, 0x58, 0x5e, 0x52, 0x61, 0xbe, 0x87, 0x98, + 0x91, 0x0c, 0x1d, 0xa1, 0x28, 0x42, 0x8c, 0x08, 0x46, 0x89, 0xc4, 0xad, 0x01, 0x51, 0xa3, 0xee, + 0x79, 0xbf, 0x04, 0x9e, 0x22, 0xaf, 0x48, 0x19, 0x5a, 0x30, 0x80, 0xb2, 0xfb, 0x3c, 0x78, 0x0b, + 0x4d, 0x7c, 0x1b, 0xb2, 0x2b, 0x9b, 0x3b, 0xb0, 0x26, 0x00, 0x4e, 0x78, 0x34, 0x7a, 0xe3, 0x11, + 0x35, 0xda, 0x54, 0xdf, 0xff, 0x36, 0xd2, 0x65, 0x21, 0x98, 0x56, 0x31, 0xc0, 0xfe, 0x2d, 0x95, + 0xac, 0x87, 0xf0, 0xd0, 0xd8, 0x3e, 0xba, 0x12, 0xdb, 0x2e, 0xaf, 0x9c, 0x01, 0x06, 0x19, 0x2c, + 0xa4, 0x81, 0xd4, 0x8b, 0x9f, 0xb3, 0x49, 0x8d, 0xb2, 0x73, 0xd2, 0x75, 0x71, 0x48, 0xb3, 0x33, + 0x59, 0x4e, 0x60, 0xc5, 0x1e, 0x96, 0xbd, 0xe2, 0x7a, 0x21, 0x9c, 0x75, 0x46, 0xba, 0x5e, 0x08, + 0x0b, 0x13, 0x12, 0x5c, 0x8b, 0x57, 0x0b, 0xd1, 0xae, 0x17, 0x58, 0x13, 0x57, 0x8d, 0x2b, 0xb9, + 0xdc, 0x81, 0x27, 0xc2, 0x92, 0xae, 0xb3, 0x57, 0xc4, 0xa1, 0xf0, 0x97, 0xda, 0x8c, 0xe7, 0x40, + 0x7b, 0x93, 0xb8, 0x03, 0x09, 0x31, 0xe2, 0xed, 0xb9, 0xce, 0x31, 0xe2, 0xed, 0x25, 0x42, 0x94, + 0x2f, 0xde, 0xb5, 0x33, 0x86, 0x5d, 0xe2, 0x9c, 0x20, 0x57, 0xb0, 0x35, 0xbf, 0xb8, 0x07, 0x09, + 0x95, 0xd2, 0x48, 0x7a, 0x84, 0xcb, 0xa4, 0xbe, 0xb1, 0x9a, 0x26, 0x19, 0x15, 0xff, 0xbb, 0x54, + 0xcd, 0x0e, 0x99, 0x05, 0xe7, 0x7c, 0x09, 0xf1, 0x0a, 0x03, 0x43, 0x9e, 0xe4, 0xc5, 0xe5, 0x64, + 0xdf, 0xdc, 0xaa, 0x5b, 0x2c, 0xee, 0xf7, 0xef, 0xc6, 0xd3, 0x37, 0xa4, 0xb9, 0xea, 0x06, 0x03, + 0xf1, 0xe2, 0x2c, 0xdc, 0xe5, 0x60, 0xeb, 0xe9, 0x82, 0xaf, 0x0f, 0xd7, 0xf1, 0xa1, 0x15, 0xc1, + 0xb5, 0xdd, 0x76, 0xe0, 0x08, 0xe7, 0x1e, 0x83, 0x3b, 0xd5, 0x4f, 0x70, 0x07, 0x2a, 0xc2, 0xc4, + 0xc6, 0xdb, 0x5c, 0x35, 0x2e, 0xa4, 0x57, 0x0d, 0xd1, 0x13, 0x09, 0x22, 0x6a, 0x99, 0x58, 0x1f, + 0x61, 0xcb, 0x95, 0x29, 0x03, 0xcd, 0x4a, 0xe9, 0x83, 0xc1, 0x08, 0xe5, 0x61, 0x8a, 0x58, 0xd0, + 0xf7, 0x52, 0xf1, 0xe3, 0xdc, 0x4f, 0x04, 0x46, 0x60, 0xf9, 0x1c, 0xb4, 0xed, 0xb4, 0xe2, 0x24, + 0x50, 0xd9, 0x01, 0x36, 0x40, 0x82, 0xb8, 0x6f, 0x5d, 0x98, 0x54, 0x1e, 0xed, 0x7a, 0x29, 0xc0, + 0x38, 0x0b, 0xfb, 0xf8, 0x36, 0xd6, 0x39, 0x3e, 0x20, 0x74, 0xe1, 0x56, 0x58, 0xf5, 0x74, 0x3a, + 0x20, 0x9b, 0x72, 0x9c, 0xbe, 0x68, 0xbc, 0x5f, 0x8c, 0x35, 0x9e, 0xc8, 0xb1, 0xe5, 0x80, 0x6b, + 0xad, 0x50, 0x9e, 0x4b, 0xea, 0x72, 0x3b, 0xc6, 0x90, 0x6d, 0x44, 0x08, 0xf2, 0xb3, 0xf3, 0x21, + 0xf8, 0x53, 0xaa, 0x43, 0x6d, 0xc8, 0x98, 0x1e, 0xdc, 0x92, 0xc2, 0x90, 0x0e, 0x85, 0x9f, 0x6a, + 0x03, 0x4a, 0xc4, 0x3a, 0x0d, 0x29, 0xd7, 0x92, 0x46, 0x08, 0x67, 0xec, 0xd3, 0x47, 0x6d, 0x87, + 0x3d, 0x36, 0x9d, 0x6e, 0x87, 0x95, 0xc3, 0x8f, 0x04, 0xa1, 0x60, 0x76, 0x42, 0x53, 0xf6, 0xdd, + 0x20, 0x23, 0x5b, 0xe3, 0x3b, 0x60, 0x5f, 0xa2, 0x6e, 0x67, 0x67, 0xc0, 0xf8, 0xec, 0x83, 0xb8, + 0x37, 0xda, 0x83, 0x16, 0xd2, 0x14, 0x8b, 0x4a, 0x6a, 0xd6, 0x4b, 0x61, 0x52, 0xae, 0xc6, 0xfb, + 0xf9, 0xd8, 0x70, 0xab, 0x5e, 0x6c, 0x65, 0x54, 0x17, 0x21, 0x27, 0x17, 0xcd, 0x62, 0xb2, 0xf2, + 0x3f, 0x34, 0x16, 0x88, 0x0b, 0x99, 0x54, 0x40, 0xb1, 0x5c, 0xaf, 0xbc, 0x4b, 0x37, 0x62, 0xb4, + 0xa1, 0x4c, 0xd1, 0x03, 0xc4, 0x5f, 0xcf, 0xbd, 0xee, 0x51, 0x33, 0x4c, 0x5a, 0x39, 0xe7, 0x97, + 0x72, 0x5a, 0xbb, 0x38, 0x38, 0x99, 0xcb, 0xf0, 0x86, 0xf2, 0x48, 0x73, 0x7f, 0x1b, 0xb7, 0x5c, + 0x4d, 0x5a, 0x70, 0xfd, 0x91, 0xd7, 0xd6, 0xc6, 0x1b, 0xcf, 0x81, 0x81, 0x8b, 0xae, 0x49, 0xd0, + 0xd7, 0x3e, 0x15, 0xc3, 0xa6, 0xfb, 0x7a, 0x1a, 0x21, 0xdc, 0x1e, 0xb9, 0x44, 0xa9, 0xad, 0x0d, + 0xab, 0x9d, 0xb1, 0xa8, 0x5d, 0x98, 0x00, 0x2e, 0x2c, 0x38, 0xb4, 0x71, 0xb5, 0x9a, 0x87, 0x6a, + 0x13, 0x8d, 0x59, 0x8b, 0xda, 0x9d, 0xdd, 0xc6, 0x13, 0x8b, 0xda, 0xb9, 0x77, 0xbc, 0x72, 0x66, + 0x54, 0xc0, 0x17, 0x66, 0xf4, 0xdc, 0x75, 0x4c, 0x54, 0xd0, 0xdc, 0x51, 0x46, 0xde, 0x7e, 0x0c, + 0xe6, 0xb1, 0x33, 0x06, 0x31, 0x30, 0x99, 0x3b, 0x1a, 0xc3, 0x65, 0xf8, 0xc9, 0x25, 0xf1, 0xac, + 0x41, 0x5e, 0x79, 0x4c, 0xbc, 0x05, 0x78, 0x0d, 0xa6, 0x0c, 0x09, 0x0b, 0x55, 0xa8, 0x4b, 0x69, + 0x7d, 0x4d, 0x32, 0xb4, 0xe4, 0x8e, 0xc6, 0x1a, 0xe5, 0xe5, 0xc7, 0x48, 0x13, 0xd4, 0xa4, 0xd5, + 0x06, 0xa0, 0x3e, 0x39, 0x2f, 0x9e, 0x52, 0x53, 0x57, 0xb2, 0x52, 0x3e, 0x73, 0xfe, 0x05, 0x7a, + 0x6e, 0x19, 0xd9, 0xf3, 0xb0, 0xb1, 0x82, 0xb9, 0x06, 0x94, 0xd1, 0x80, 0xe7, 0x5c, 0x05, 0xed, + 0x0a, 0x88, 0x11, 0x3d, 0xb5, 0x09, 0x8f, 0x2e, 0x4e, 0x58, 0x2c, 0xc4, 0xc0, 0x30, 0xef, 0x4d, + 0xb9, 0x05, 0xca, 0x2c, 0xfc, 0xaf, 0x6f, 0x3c, 0xc8, 0x76, 0x34, 0xf7, 0x8e, 0x87, 0x3b, 0xe0, + 0x91, 0x33, 0x99, 0x40, 0xa8, 0x3d, 0x44, 0x02, 0x40, 0x26, 0xd7, 0x4e, 0x96, 0x65, 0xe4, 0x54, + 0x56, 0xe8, 0x1b, 0x79, 0x7c, 0x56, 0xd0, 0x1e, 0xbb, 0x83, 0x27, 0x78, 0xa2, 0xd1, 0x5b, 0xb4, + 0x29, 0xbf, 0x62, 0xd4, 0xc0, 0xc6, 0xe4, 0x4f, 0x39, 0xe3, 0x7c, 0xcc, 0x95, 0xc2, 0x70, 0x6f, + 0x36, 0x88, 0x20, 0xb4, 0x6f, 0x35, 0x55, 0x7f, 0x26, 0xcc, 0x3b, 0x8a, 0x56, 0x29, 0xa5, 0x91, + 0x1e, 0x24, 0x8e, 0xbf, 0x58, 0x31, 0x3d, 0xad, 0x26, 0x73, 0x99, 0x3f, 0x9b, 0x9c, 0x11, 0x3c, + 0x32, 0xdf, 0x55, 0xaa, 0xc1, 0xf9, 0x4e, 0xd9, 0x32, 0x3b, 0xb8, 0x0f, 0x06, 0x9e, 0xb4, 0x67, + 0x79, 0xe8, 0x40, 0x26, 0x74, 0x58, 0x0b, 0x22, 0xe3, 0x75, 0xdd, 0xe0, 0x3c, 0x8a, 0x06, 0xf0, + 0x63, 0x3d, 0xb2, 0xc6, 0xc5, 0x34, 0xab, 0x25, 0x26, 0xa0, 0x92, 0x97, 0x9c, 0x74, 0xd5, 0xff, + 0xd2, 0x35, 0x18, 0xb1, 0x2d, 0x42, 0xf4, 0xfc, 0xc6, 0x37, 0x0d, 0x93, 0xc7, 0x82, 0xc9, 0x13, + 0x3e, 0xce, 0xe5, 0x6d, 0x11, 0x3d, 0x2d, 0xc6, 0x73, 0x2b, 0x5d, 0xb7, 0xa2, 0xb9, 0x8c, 0xfa, + 0x11, 0x43, 0x80, 0xa0, 0x8e, 0xd7, 0x03, 0x43, 0x71, 0x97, 0x96, 0xf7, 0x1b, 0x4f, 0x70, 0x47, + 0x27, 0x93, 0x36, 0xcd, 0x2f, 0x97, 0x62, 0xcb, 0x86, 0xdf, 0xf8, 0xe2, 0x20, 0x71, 0x4c, 0x4d, + 0x9c, 0xf0, 0x8d, 0x85, 0x44, 0xcb, 0xd2, 0xa8, 0x6d, 0x73, 0xc5, 0x86, 0x16, 0xf1, 0x76, 0xc0, + 0x79, 0x3f, 0xf1, 0x83, 0xd7, 0x28, 0x55, 0xea, 0xfb, 0xbf, 0xe2, 0xf6, 0x9d, 0x65, 0x5b, 0x21, + 0x76, 0xf5, 0xb3, 0xdd, 0xe4, 0x8a, 0x77, 0x70, 0x3a, 0xdb, 0x16, 0xd3, 0x0a, 0x13, 0x4c, 0x3a, + 0x69, 0xf4, 0x7d, 0x04, 0xd3, 0x35, 0xfa, 0x37, 0x44, 0x0f, 0xd5, 0x4f, 0x8e, 0x18, 0x12, 0x32, + 0xa6, 0x12, 0x39, 0xc2, 0x1d, 0xe0, 0xd0, 0x4e, 0x4e, 0x02, 0x4c, 0xdc, 0x27, 0x84, 0x7b, 0x81, + 0x90, 0xe5, 0x74, 0xf5, 0x4d, 0xdb, 0x39, 0x0b, 0xf4, 0xbb, 0x31, 0x72, 0x9e, 0xfc, 0x34, 0xeb, + 0x33, 0x42, 0xf6, 0x8f, 0xd4, 0x6c, 0x9b, 0x52, 0x34, 0x14, 0xdc, 0x69, 0x61, 0x7b, 0x7d, 0xf1, + 0xd9, 0xb5, 0x63, 0x96, 0xce, 0x73, 0xc6, 0x40, 0x1c, 0x89, 0xa6, 0x15, 0xa3, 0xa0, 0x9a, 0xf0, + 0xec, 0x0c, 0x5f, 0x67, 0xf6, 0xfe, 0x79, 0xae, 0xc7, 0xe6, 0x39, 0xbf, 0x28, 0x0d, 0xb3, 0xb7, + 0xad, 0xc5, 0xd3, 0x0e, 0xdf, 0xd2, 0xe6, 0x3a, 0x8c, 0xd7, 0xf0, 0x14, 0x69, 0x69, 0xb8, 0xfd, + 0x33, 0x9a, 0x7f, 0x69, 0x38, 0xff, 0x3f, 0xd5, 0xfc, 0xab, 0x34, 0xff, 0x58, 0x28, 0xdf, 0xf9, + 0x62, 0xa9, 0xc6, 0xfe, 0x05, 0xcd, 0xfb, 0xdd, 0xdd, 0xbc, 0x8d, 0x50, 0xef, 0x77, 0xf4, 0x14, + 0xc5, 0xbf, 0xdd, 0xcd, 0x5b, 0x00, 0x7d, 0x0d, 0x99, 0x31, 0x4f, 0x1c, 0x86, 0xf9, 0x14, 0x5a, + 0xac, 0x8c, 0x40, 0x8a, 0x9f, 0xab, 0xce, 0x85, 0x57, 0xdc, 0x0f, 0xad, 0x5e, 0x81, 0x61, 0x61, + 0xf8, 0x3c, 0x6a, 0xbb, 0x32, 0x5c, 0x2f, 0x06, 0xe6, 0xc9, 0x4f, 0x06, 0x04, 0x70, 0x1a, 0x52, + 0x7a, 0xb9, 0x37, 0x3d, 0x8d, 0x9a, 0x70, 0x86, 0x6d, 0x10, 0x9b, 0xc2, 0x3a, 0x67, 0xfe, 0xb3, + 0x62, 0xb6, 0x41, 0x85, 0x96, 0xd9, 0x80, 0x25, 0x1c, 0xdf, 0xd0, 0x38, 0xbc, 0xbc, 0x04, 0xfe, + 0xaf, 0xa0, 0x93, 0x79, 0xf0, 0xdc, 0x07, 0x1a, 0x23, 0xfe, 0x03, 0xed, 0xe6, 0xbb, 0x78, 0xae, + 0xa2, 0xda, 0x23, 0x8d, 0x6b, 0x99, 0xa1, 0x61, 0x9c, 0xb1, 0x40, 0x60, 0xbd, 0x32, 0xfb, 0x13, + 0x56, 0xcd, 0x57, 0x73, 0xc5, 0x5b, 0xe1, 0x87, 0xa6, 0xad, 0x81, 0xc8, 0xf6, 0xb7, 0x6b, 0x30, + 0xb2, 0x3d, 0x09, 0x71, 0x7d, 0xe6, 0xc9, 0x1c, 0xe5, 0x6d, 0xea, 0xcb, 0x6a, 0x02, 0xc2, 0x80, + 0x4d, 0xf9, 0x60, 0xac, 0xba, 0x95, 0xc0, 0xe2, 0xf1, 0x89, 0x97, 0xd4, 0x02, 0x30, 0x5c, 0x8b, + 0x27, 0x8c, 0x3c, 0xbd, 0xe2, 0x4c, 0x71, 0x55, 0x6a, 0x19, 0xe7, 0x7c, 0xd7, 0xb2, 0x4d, 0x78, + 0xe2, 0xbf, 0xee, 0xc7, 0x30, 0xfb, 0x1f, 0xea, 0x35, 0x23, 0xcc, 0xe6, 0x1c, 0xfb, 0x25, 0x3c, + 0x50, 0x91, 0xa9, 0xc2, 0x51, 0x5e, 0xfe, 0x8e, 0x61, 0x14, 0xe3, 0x21, 0x6a, 0xfd, 0x3e, 0x59, + 0x1d, 0xc6, 0xd8, 0x33, 0x80, 0x92, 0xca, 0xfd, 0x2a, 0x60, 0x65, 0xfb, 0xe9, 0xe1, 0x58, 0x2e, + 0x39, 0xe8, 0xcb, 0x72, 0xee, 0x7a, 0x1a, 0x4d, 0x81, 0x81, 0x1e, 0x6b, 0x4a, 0xe0, 0xaa, 0x7f, + 0x4f, 0x23, 0xee, 0x58, 0x50, 0x6d, 0xc9, 0x11, 0xcb, 0xed, 0x73, 0x68, 0x70, 0xe9, 0x87, 0x08, + 0x0a, 0x19, 0x62, 0xcf, 0x80, 0x54, 0xc6, 0xd4, 0xd3, 0x13, 0x10, 0xc4, 0xda, 0x96, 0x4b, 0x84, + 0x0b, 0x36, 0xe5, 0x9b, 0xb3, 0x6a, 0x44, 0xe3, 0x25, 0x17, 0xc5, 0x17, 0x0d, 0x2c, 0xa9, 0xf4, + 0x0b, 0x93, 0xa4, 0x8c, 0xd9, 0xc6, 0x66, 0x72, 0x52, 0x7a, 0x7c, 0x8e, 0xb1, 0x3b, 0xca, 0x4b, + 0x5a, 0x55, 0xe1, 0x81, 0xa0, 0x28, 0xb8, 0x16, 0x24, 0xbe, 0x98, 0xc8, 0x48, 0x19, 0xb1, 0x44, + 0x68, 0x17, 0x26, 0x72, 0xfb, 0x32, 0x34, 0x66, 0xa5, 0x26, 0x3e, 0xe8, 0x37, 0x24, 0x42, 0xbe, + 0x64, 0x49, 0x26, 0xd6, 0xd3, 0xd2, 0xe3, 0x0b, 0x88, 0xa9, 0x59, 0xde, 0x1f, 0x50, 0xcf, 0xbd, + 0xaf, 0xf0, 0x7b, 0x87, 0xa2, 0x48, 0xbf, 0x37, 0x30, 0x3d, 0xcf, 0x96, 0x93, 0xab, 0x6c, 0xbb, + 0xdb, 0xad, 0xf5, 0x5a, 0xff, 0x97, 0x84, 0x6f, 0x01, 0x1d, 0xb9, 0xc6, 0x5e, 0x24, 0xa6, 0xe3, + 0xb8, 0x33, 0x30, 0x24, 0x99, 0x4e, 0x3f, 0x68, 0x6a, 0x91, 0xf8, 0xe6, 0x78, 0xbf, 0xb1, 0x2f, + 0xaa, 0x99, 0x73, 0x5f, 0xc0, 0xd9, 0xe1, 0x45, 0x8d, 0xf4, 0xb8, 0x46, 0xca, 0x6f, 0xe7, 0xf6, + 0x5d, 0x86, 0x19, 0xad, 0xff, 0x06, 0x46, 0x5b, 0xda, 0x70, 0xfe, 0xf8, 0x44, 0xeb, 0xb5, 0xbc, + 0x5c, 0x73, 0xc0, 0x91, 0x68, 0x51, 0xde, 0x3b, 0x1f, 0x3c, 0x9f, 0xe8, 0x9c, 0x8c, 0xf3, 0x6b, + 0xf5, 0x2f, 0x10, 0xdd, 0xa6, 0x80, 0x78, 0x11, 0x66, 0xa7, 0x28, 0xbf, 0x70, 0xac, 0x53, 0x42, + 0xa7, 0x31, 0xc3, 0xc0, 0xd2, 0xe8, 0xaf, 0x83, 0x3c, 0x3e, 0x5b, 0x12, 0xda, 0x89, 0x63, 0x0e, + 0xc4, 0xcf, 0x12, 0x1f, 0x47, 0x4e, 0x12, 0x6f, 0xd2, 0x2d, 0xa9, 0x32, 0x61, 0x4a, 0x65, 0x17, + 0x69, 0x81, 0x50, 0xae, 0xff, 0x0b, 0x6e, 0x5f, 0x2f, 0x7b, 0x51, 0xb2, 0x5e, 0x48, 0xaa, 0x97, + 0xf8, 0xb6, 0x78, 0x7f, 0xd2, 0x79, 0xd5, 0x4c, 0x35, 0xa6, 0x5c, 0x26, 0x03, 0x10, 0x69, 0x41, + 0x2c, 0x57, 0x09, 0x7f, 0x01, 0x1f, 0x1d, 0x3b, 0x00, 0xe6, 0x30, 0x3c, 0x27, 0xd1, 0x92, 0x6b, + 0x56, 0x8e, 0xdd, 0x17, 0x3c, 0xa0, 0xa7, 0x63, 0x3f, 0x03, 0x1c, 0x63, 0x7a, 0x96, 0x54, 0xc6, + 0x91, 0x96, 0x29, 0x7c, 0x82, 0xca, 0x19, 0x6e, 0xf7, 0x16, 0x50, 0xd4, 0xfd, 0x2c, 0x9a, 0x63, + 0xf1, 0x78, 0xb2, 0xba, 0x98, 0xfe, 0xc4, 0x2a, 0xca, 0xf5, 0x35, 0xdf, 0x0d, 0xf3, 0xf8, 0x29, + 0xb9, 0xf2, 0xed, 0xd2, 0xa7, 0xf0, 0x08, 0xb3, 0x78, 0x9f, 0x6a, 0xff, 0x4e, 0xfc, 0x89, 0x85, + 0x49, 0x40, 0xd2, 0xc8, 0xb8, 0x4c, 0x0d, 0xa1, 0xd4, 0xad, 0xe9, 0xa5, 0x4c, 0xe9, 0x53, 0xe0, + 0xc1, 0xa3, 0x91, 0xbc, 0x41, 0x75, 0x0b, 0x2f, 0x7e, 0x4d, 0xa3, 0x27, 0x9b, 0xee, 0x1d, 0x0c, + 0xe9, 0x9f, 0xde, 0xe8, 0xe9, 0x6b, 0x60, 0x69, 0x24, 0x4a, 0xba, 0x05, 0x8f, 0x2f, 0xa9, 0xaa, + 0xf2, 0x5d, 0x70, 0x4b, 0x18, 0x61, 0x9a, 0xc4, 0x5f, 0x03, 0x2b, 0x47, 0xd2, 0xe9, 0x91, 0xd6, + 0x74, 0xad, 0xc4, 0xb7, 0x48, 0xa6, 0x0b, 0x64, 0xa5, 0x86, 0x84, 0x85, 0xd0, 0x7b, 0x6a, 0xd4, + 0xd6, 0x6b, 0x26, 0xd8, 0x25, 0xb9, 0x12, 0x42, 0xbe, 0x31, 0x78, 0xaf, 0xc1, 0x52, 0xca, 0x5a, + 0xec, 0x47, 0xf1, 0xac, 0x91, 0x4d, 0xd9, 0xa0, 0xf6, 0xce, 0x1d, 0x18, 0xf3, 0xe1, 0x4b, 0x9c, + 0x7b, 0x1b, 0x64, 0xd2, 0xd2, 0x33, 0x6a, 0x29, 0x1f, 0x2a, 0xe5, 0x7b, 0xb0, 0x18, 0x4f, 0x3a, + 0x04, 0x9b, 0x5f, 0x57, 0x2b, 0x24, 0x8e, 0xae, 0xf0, 0x48, 0xa8, 0xfd, 0x37, 0x6a, 0x71, 0xc4, + 0xe8, 0xe2, 0x38, 0xda, 0x9e, 0x1e, 0xe5, 0x23, 0x7e, 0x59, 0xf8, 0xa3, 0x25, 0xc7, 0x52, 0xaa, + 0xb1, 0x99, 0x95, 0xeb, 0x74, 0xa3, 0x3e, 0x8e, 0xee, 0xa2, 0x9b, 0xed, 0xf7, 0xac, 0x46, 0x37, + 0x5b, 0x9c, 0x19, 0x5c, 0xeb, 0xe1, 0xaa, 0xf1, 0x9a, 0x02, 0xdd, 0xd9, 0xb4, 0x98, 0x2d, 0xa5, + 0xe1, 0x36, 0x74, 0x6f, 0x7e, 0x1f, 0x6c, 0x41, 0xf7, 0x3b, 0xed, 0xe1, 0x39, 0xd8, 0x22, 0x67, + 0xb8, 0xc5, 0x3e, 0x7a, 0x7f, 0xa3, 0x2e, 0x3c, 0xd8, 0x66, 0x21, 0x6d, 0xb3, 0x3d, 0xd8, 0x26, + 0x9c, 0xb6, 0xc1, 0x7d, 0x07, 0x9b, 0x32, 0x35, 0xd4, 0xc6, 0xf9, 0x92, 0x45, 0x2d, 0xb0, 0x94, + 0xe6, 0xd2, 0xda, 0x2b, 0xff, 0x49, 0xed, 0x6f, 0x67, 0x84, 0x6a, 0xe7, 0x00, 0xf4, 0x88, 0x51, + 0x18, 0x4d, 0x0e, 0xd6, 0x8f, 0xa0, 0xf5, 0x4f, 0xd0, 0x31, 0x1c, 0xbb, 0x5b, 0x7f, 0x86, 0xa5, + 0x34, 0xcc, 0x62, 0x5f, 0x14, 0xda, 0x20, 0xfc, 0xdf, 0xdb, 0x2a, 0x5d, 0x0e, 0xf2, 0x3d, 0xea, + 0x06, 0xe3, 0x5b, 0x0d, 0xb8, 0x5f, 0x9e, 0x19, 0x62, 0x9a, 0x1a, 0xf9, 0x1b, 0xfb, 0xf2, 0x94, + 0xc5, 0xea, 0xdc, 0x00, 0x0e, 0xc4, 0x64, 0xa3, 0x47, 0x16, 0x6e, 0x9a, 0x61, 0x6a, 0xb5, 0xe3, + 0x29, 0x0f, 0x5b, 0x9e, 0xf2, 0x6b, 0x15, 0x8a, 0xb4, 0x10, 0xc3, 0x19, 0xcd, 0xf0, 0x46, 0x61, + 0x55, 0x57, 0x2c, 0xae, 0x63, 0xba, 0xdb, 0xd1, 0xdb, 0x7b, 0x0a, 0x97, 0x71, 0x07, 0x0d, 0xc1, + 0x89, 0xf8, 0x4f, 0xac, 0xb4, 0xd4, 0x4d, 0xa5, 0x70, 0xc8, 0x3b, 0x44, 0xa5, 0xd0, 0x96, 0xa7, + 0x56, 0xa4, 0x13, 0xb6, 0xf5, 0xf6, 0x48, 0x59, 0x0c, 0x16, 0x28, 0xee, 0xfe, 0x90, 0x44, 0xc6, + 0x86, 0xe4, 0x91, 0x9e, 0x33, 0x11, 0xfe, 0xd4, 0xb9, 0x19, 0x7e, 0xab, 0x8e, 0x28, 0xb8, 0xb7, + 0x09, 0x82, 0xc9, 0xb9, 0x71, 0xc3, 0x9d, 0xdc, 0xc6, 0xa9, 0x26, 0x00, 0xf3, 0x5f, 0x8a, 0x3b, + 0x19, 0xcf, 0x98, 0xbc, 0xfc, 0x05, 0x8c, 0xfb, 0x90, 0x8b, 0x9e, 0x72, 0x51, 0xcf, 0x47, 0xe7, + 0x80, 0xb6, 0x15, 0x1b, 0x82, 0xa7, 0xa3, 0x67, 0x63, 0x9d, 0x7d, 0x7e, 0x02, 0x3a, 0x07, 0x73, + 0x2f, 0xdb, 0x23, 0xc9, 0x73, 0x68, 0xce, 0x59, 0x72, 0xdd, 0xfb, 0xe5, 0x18, 0xb6, 0x31, 0xa6, + 0x15, 0xe2, 0xe7, 0x3a, 0xf5, 0x68, 0x8d, 0x2d, 0x78, 0xbe, 0x1a, 0xe6, 0x05, 0x9b, 0xf2, 0x6b, + 0xaa, 0x29, 0x71, 0x32, 0x7f, 0xd8, 0x78, 0x82, 0x2c, 0xd7, 0x91, 0xe5, 0x5a, 0xb2, 0x5c, 0x43, + 0xb4, 0xb2, 0xbc, 0x0a, 0xbd, 0x18, 0xbd, 0x39, 0x47, 0x79, 0xd4, 0x70, 0x57, 0x24, 0xc6, 0x03, + 0x0e, 0x52, 0x24, 0x5d, 0xb5, 0x80, 0x40, 0x97, 0xa4, 0x69, 0xd0, 0x87, 0x4d, 0xd3, 0xd6, 0x66, + 0xe9, 0x6a, 0xd2, 0x74, 0x19, 0xe4, 0x47, 0x7a, 0x29, 0x2b, 0x96, 0xa4, 0xc5, 0x4a, 0x32, 0x9d, + 0xe0, 0x7e, 0x49, 0x0d, 0x60, 0x80, 0x5b, 0xf1, 0x19, 0xf9, 0xcc, 0x1b, 0x88, 0xf2, 0xde, 0x9e, + 0x4e, 0xce, 0x80, 0x51, 0x01, 0xf7, 0x12, 0x11, 0xfc, 0xf8, 0x19, 0xdc, 0x22, 0x16, 0xba, 0xb8, + 0x7d, 0xfd, 0x68, 0x66, 0x40, 0x11, 0x93, 0x49, 0xc5, 0x02, 0x72, 0x51, 0x3d, 0xe9, 0x9d, 0xd4, + 0xac, 0x9e, 0xf5, 0x9e, 0x62, 0xea, 0x12, 0x3d, 0x2c, 0xf8, 0xba, 0x30, 0x14, 0x6e, 0x5f, 0x1b, + 0xb4, 0xbc, 0xc2, 0x9e, 0xc4, 0x23, 0xf1, 0x36, 0xf0, 0x05, 0x75, 0x24, 0x0b, 0x10, 0xbf, 0x06, + 0xc2, 0x7f, 0xe5, 0x1b, 0xea, 0x06, 0xe0, 0xf2, 0xf3, 0x0b, 0x78, 0x1e, 0x9b, 0x57, 0x48, 0x96, + 0x19, 0x2c, 0x25, 0xc9, 0x5a, 0x85, 0x6a, 0x6e, 0x6a, 0x27, 0xab, 0x97, 0x93, 0xac, 0xcc, 0xfd, + 0x6c, 0x67, 0x3e, 0x14, 0x1f, 0x1b, 0x42, 0xd2, 0xe2, 0xe8, 0x0d, 0x77, 0x82, 0x92, 0xc1, 0x55, + 0x8b, 0xd8, 0x2e, 0x5f, 0x2f, 0xde, 0xd6, 0x70, 0xaf, 0x6e, 0xc4, 0x03, 0x7a, 0x78, 0xf6, 0xa3, + 0x85, 0xfa, 0xcc, 0x99, 0xe0, 0xff, 0xcb, 0x19, 0x77, 0x08, 0x7f, 0x01, 0x5d, 0x7d, 0x6f, 0xbb, + 0x26, 0xe2, 0x28, 0xdd, 0x2a, 0xcd, 0x29, 0xd5, 0xe7, 0x98, 0x01, 0x01, 0xf0, 0x43, 0x9e, 0xb9, + 0x15, 0x52, 0x52, 0x70, 0xb0, 0x39, 0x67, 0x94, 0x38, 0x10, 0xc1, 0xb9, 0x07, 0x91, 0x91, 0xfc, + 0x69, 0x88, 0xa2, 0xe5, 0x3c, 0x96, 0xee, 0x01, 0x1d, 0x8a, 0xc7, 0x3d, 0xcb, 0x23, 0x78, 0xd2, + 0xb7, 0xf7, 0x77, 0x52, 0x24, 0xa1, 0x8c, 0x40, 0x52, 0xd2, 0xe3, 0xc5, 0x48, 0x4d, 0x7a, 0xfe, + 0x1b, 0x09, 0x4a, 0x8f, 0x83, 0x1b, 0x03, 0x80, 0x0f, 0x79, 0x6b, 0x15, 0x2d, 0x8c, 0x25, 0x6e, + 0x33, 0xd2, 0xec, 0x88, 0x7a, 0xfc, 0xbe, 0x23, 0x74, 0xfc, 0x5e, 0x21, 0x47, 0xb6, 0xd3, 0xa3, + 0xe3, 0xf4, 0x12, 0xc3, 0xc7, 0x78, 0x2a, 0x87, 0x9a, 0x6a, 0xe7, 0xd3, 0xc6, 0x80, 0x94, 0x7f, + 0xc1, 0xd8, 0x47, 0xfc, 0xdc, 0xde, 0x81, 0x28, 0x72, 0xcb, 0x7b, 0x23, 0xaa, 0xea, 0xc4, 0x19, + 0xba, 0x2b, 0x81, 0x9c, 0x0d, 0x8a, 0x66, 0xe8, 0x80, 0xff, 0x3b, 0x03, 0xc1, 0x21, 0xb8, 0x3b, + 0xe8, 0x71, 0x1b, 0xce, 0x19, 0x01, 0xa3, 0x10, 0xb4, 0x12, 0x15, 0x4d, 0x63, 0xdf, 0xf0, 0xb8, + 0x38, 0x00, 0xf1, 0xb8, 0xf0, 0x9b, 0x51, 0x60, 0x8f, 0xfe, 0x2b, 0xb0, 0x59, 0x2a, 0x58, 0xd7, + 0x11, 0x84, 0xca, 0xd4, 0x05, 0xe8, 0x59, 0x7d, 0xbc, 0xc1, 0xc7, 0x55, 0x9f, 0xa1, 0x47, 0x79, + 0xe8, 0xcd, 0x8e, 0x70, 0x89, 0x52, 0x00, 0xc3, 0x6f, 0x4a, 0x01, 0x88, 0xc9, 0x6b, 0x29, 0x05, + 0x6a, 0x32, 0xc0, 0x3e, 0xb7, 0x90, 0x0c, 0xbd, 0xa4, 0x0e, 0x3e, 0x23, 0x36, 0xfc, 0x08, 0x0e, + 0x7b, 0xe2, 0xc7, 0x48, 0x85, 0x70, 0x8a, 0x9b, 0x78, 0x91, 0x21, 0x2f, 0x26, 0x13, 0xc7, 0x02, + 0xc9, 0xdd, 0x85, 0x17, 0xae, 0x32, 0x16, 0x35, 0x65, 0x2c, 0x55, 0xcf, 0x09, 0xd1, 0x23, 0x4a, + 0x19, 0x71, 0x16, 0x90, 0x6f, 0xb3, 0xf2, 0xe7, 0xae, 0xa0, 0x94, 0x38, 0xc1, 0xf8, 0x37, 0x4b, + 0xd6, 0x36, 0x6a, 0xfc, 0x8f, 0x53, 0xe3, 0x7f, 0x58, 0x32, 0x79, 0x46, 0x18, 0xff, 0x9a, 0x8c, + 0x54, 0x8b, 0x52, 0xda, 0x15, 0x5a, 0x8a, 0x1b, 0x1f, 0xdc, 0x57, 0x24, 0x19, 0x9b, 0xa0, 0x3c, + 0x2a, 0x98, 0xc2, 0x6a, 0xf6, 0xc6, 0x8c, 0xb5, 0x0c, 0x3d, 0xb1, 0xf7, 0x9d, 0x2a, 0x54, 0x20, + 0x43, 0x52, 0x65, 0x97, 0xc4, 0x9f, 0x46, 0x52, 0x55, 0x5f, 0xa2, 0xd7, 0xc4, 0x38, 0x75, 0xac, + 0xd9, 0x62, 0x40, 0xc3, 0xb9, 0x71, 0x03, 0x94, 0x2a, 0x77, 0xa7, 0x9e, 0xde, 0x5b, 0x0b, 0xc9, + 0x13, 0xbd, 0xe3, 0xd7, 0x2d, 0x0b, 0xd7, 0x2c, 0xa5, 0x7a, 0x8b, 0xd9, 0x96, 0xa3, 0xe8, 0xfa, + 0x55, 0xca, 0xed, 0xd2, 0x30, 0x5c, 0xf5, 0x1b, 0x74, 0xda, 0xd6, 0x49, 0x2c, 0x9e, 0x76, 0x8c, + 0x94, 0xd2, 0x34, 0x24, 0x4b, 0x23, 0xa5, 0x69, 0x49, 0x96, 0xb6, 0x36, 0x4d, 0x57, 0x93, 0xa5, + 0xcb, 0x26, 0xbb, 0xf4, 0x52, 0x5a, 0x2c, 0x6e, 0x65, 0x82, 0x64, 0x3c, 0xbd, 0x80, 0x64, 0x25, + 0xa3, 0x64, 0x3c, 0xbd, 0x94, 0xde, 0x1f, 0x89, 0x53, 0xb9, 0x01, 0x9a, 0xb2, 0xdf, 0x17, 0xa2, + 0xc1, 0xfd, 0x92, 0x7a, 0xe3, 0x00, 0x14, 0x45, 0x25, 0x39, 0xe8, 0x8a, 0x2a, 0x8f, 0x32, 0x65, + 0x05, 0xd5, 0x98, 0x3f, 0xb1, 0x35, 0x4f, 0xa7, 0x82, 0x78, 0xd3, 0x56, 0xe0, 0x50, 0x01, 0x2d, + 0x62, 0x48, 0x16, 0x12, 0x41, 0x87, 0x3b, 0xf5, 0x39, 0xc6, 0xc0, 0x1a, 0xdf, 0x2a, 0xa0, 0x43, + 0x96, 0xbd, 0x31, 0x0b, 0xe8, 0x90, 0x86, 0xaf, 0x50, 0x3f, 0x79, 0x44, 0xfd, 0x31, 0x6a, 0xfd, + 0xb0, 0x50, 0x2d, 0x56, 0x56, 0xe5, 0x39, 0x4c, 0x02, 0x72, 0x67, 0xad, 0x23, 0xab, 0x9f, 0x92, + 0xd2, 0x61, 0x1c, 0xcf, 0x48, 0xe9, 0xa0, 0xcf, 0x85, 0x18, 0x4a, 0xc7, 0x86, 0xb6, 0x0a, 0xc4, + 0x65, 0x78, 0x58, 0x1c, 0x04, 0x99, 0x9a, 0x73, 0x6a, 0xcd, 0xdf, 0xc3, 0x73, 0xe4, 0x92, 0x6e, + 0xbf, 0x6b, 0x47, 0x2a, 0xe3, 0x9c, 0x22, 0x7a, 0x33, 0x4b, 0xf5, 0x79, 0x39, 0xca, 0xcf, 0xa7, + 0x04, 0x6d, 0x14, 0x2d, 0x76, 0x1a, 0x69, 0x85, 0xb5, 0x8c, 0x33, 0x4e, 0xf4, 0xae, 0xa3, 0x15, + 0x76, 0x8c, 0xae, 0xa0, 0xcf, 0x5a, 0xf2, 0x30, 0x82, 0xae, 0xf8, 0x18, 0xe2, 0xaa, 0x48, 0xa3, + 0xa7, 0x41, 0xd2, 0xec, 0x47, 0xdb, 0x4f, 0x0f, 0xac, 0x03, 0xce, 0xcb, 0x86, 0x3b, 0x54, 0x4f, + 0xae, 0x4b, 0xb1, 0x7f, 0x70, 0xbd, 0x60, 0x87, 0x1e, 0xf3, 0x02, 0x15, 0x9b, 0x94, 0xc8, 0xee, + 0xe0, 0x9a, 0xa8, 0x5a, 0xe8, 0x8c, 0xa1, 0xed, 0xb2, 0x52, 0x1a, 0x2b, 0x2e, 0xdd, 0x85, 0xf7, + 0x07, 0x84, 0x27, 0x8d, 0xa3, 0x00, 0x4f, 0x38, 0xe7, 0x07, 0xa3, 0x1b, 0xab, 0x1e, 0x44, 0xa4, + 0x36, 0x5f, 0x2b, 0x2d, 0xa3, 0x50, 0xc7, 0xa4, 0x94, 0x6b, 0x85, 0xe8, 0x45, 0xeb, 0x74, 0x42, + 0x44, 0x8a, 0x59, 0xef, 0xd4, 0x8a, 0x4d, 0x9a, 0x15, 0x42, 0x67, 0x30, 0x52, 0x45, 0x30, 0xa1, + 0xf6, 0xd3, 0x68, 0xa0, 0x6d, 0xd5, 0x4a, 0x0f, 0xd3, 0x76, 0x91, 0x29, 0x58, 0xb9, 0x11, 0x2a, + 0xdf, 0xa4, 0x01, 0x35, 0x54, 0x85, 0x0a, 0x60, 0xf1, 0xb4, 0x32, 0xae, 0xde, 0xdf, 0xc9, 0x31, + 0x07, 0x17, 0x49, 0x75, 0x23, 0xef, 0x9c, 0xd1, 0x4b, 0x9d, 0xb2, 0xe0, 0x57, 0xaf, 0x23, 0x82, + 0x6d, 0x69, 0x08, 0xe3, 0x0e, 0x64, 0x0c, 0xa1, 0x65, 0xff, 0x1a, 0x17, 0x77, 0x06, 0x66, 0x39, + 0x13, 0xaa, 0x02, 0x43, 0xb8, 0xbf, 0x1e, 0x5d, 0xf3, 0xca, 0xef, 0xa1, 0xa3, 0x6c, 0xf0, 0x8a, + 0x1b, 0xe9, 0x1b, 0x93, 0xe1, 0x3b, 0x0f, 0x95, 0xc1, 0x2e, 0x3c, 0xfb, 0xd2, 0x22, 0x71, 0x20, + 0x77, 0x57, 0x9e, 0x38, 0x60, 0xe1, 0xaa, 0x1f, 0xc3, 0xa5, 0x9a, 0x01, 0x2b, 0x57, 0x7d, 0x2f, + 0x7d, 0x59, 0xc7, 0xb9, 0xab, 0xe8, 0x19, 0x13, 0xb9, 0x42, 0x0b, 0x6e, 0xe4, 0x04, 0x72, 0x2b, + 0x50, 0xae, 0x51, 0x7e, 0x00, 0xb8, 0x74, 0x46, 0xd1, 0x63, 0x64, 0xaf, 0x89, 0xb7, 0xb4, 0xdb, + 0xd2, 0x03, 0x89, 0xb2, 0x82, 0xf3, 0xe7, 0x25, 0x69, 0x02, 0x8c, 0x98, 0x74, 0x83, 0xf3, 0x17, + 0x89, 0x75, 0x3e, 0xa0, 0x40, 0xee, 0x73, 0xae, 0x12, 0x07, 0x32, 0x55, 0x47, 0xe8, 0x7b, 0x90, + 0x9e, 0x06, 0x23, 0xdd, 0x79, 0x8c, 0xea, 0xd4, 0x06, 0xae, 0xda, 0x45, 0xab, 0x17, 0x72, 0xee, + 0x71, 0xea, 0x61, 0x38, 0x0a, 0xac, 0x05, 0xe3, 0xd6, 0x6e, 0xb3, 0x32, 0x1f, 0xab, 0xe2, 0x81, + 0x63, 0x29, 0x4c, 0xac, 0xd7, 0xe0, 0x35, 0x5c, 0x5e, 0x31, 0x2b, 0x8f, 0xfa, 0xd5, 0x30, 0xd1, + 0x2b, 0x7a, 0x71, 0xdc, 0x7b, 0x6c, 0xd8, 0xf2, 0xa4, 0x5c, 0x1e, 0x58, 0x81, 0xfb, 0x34, 0x26, + 0x05, 0x82, 0xfa, 0xc0, 0x7d, 0xe8, 0x1e, 0xfb, 0x85, 0x76, 0x77, 0x9f, 0xf3, 0xa1, 0x3a, 0x5c, + 0x38, 0xae, 0x0a, 0xe0, 0x5f, 0x49, 0x50, 0x9c, 0x53, 0x49, 0x6b, 0xed, 0x24, 0x39, 0x9b, 0xad, + 0xf9, 0x37, 0xa4, 0x89, 0xd8, 0xc9, 0x56, 0x8c, 0xcd, 0x52, 0x29, 0x46, 0x9a, 0x84, 0xbf, 0xe1, + 0xe2, 0x65, 0x13, 0xd0, 0x37, 0x48, 0x31, 0x70, 0x83, 0x3b, 0x6b, 0xff, 0x71, 0x0c, 0xcf, 0x07, + 0xf7, 0x9d, 0x7b, 0xc8, 0x50, 0x27, 0xae, 0x56, 0x49, 0xd1, 0x72, 0x3a, 0x3d, 0x63, 0x83, 0x77, + 0xdc, 0xa5, 0x5c, 0x8d, 0xfb, 0x1c, 0x57, 0xbd, 0x92, 0xce, 0x1c, 0x1d, 0x47, 0x87, 0x7b, 0x77, + 0x26, 0xac, 0xac, 0x65, 0xe5, 0x6d, 0xac, 0xca, 0x17, 0xf1, 0x6b, 0xe8, 0x39, 0x2d, 0xd8, 0x73, + 0x3f, 0xf4, 0x2c, 0xf8, 0xa1, 0x17, 0xbc, 0x18, 0xda, 0xd1, 0x39, 0x1e, 0xdd, 0x09, 0x5a, 0xc2, + 0xbd, 0xd2, 0x09, 0x20, 0x55, 0x6c, 0x1e, 0xcb, 0xee, 0xc4, 0xeb, 0x4c, 0x94, 0x18, 0xc8, 0x70, + 0x5c, 0x98, 0xa8, 0xd5, 0x56, 0x43, 0xb7, 0xff, 0x0d, 0x6f, 0xa9, 0x6a, 0x27, 0xea, 0x1d, 0xdd, + 0x9a, 0x1f, 0x53, 0xd6, 0xd7, 0x6a, 0x53, 0xab, 0x4f, 0x08, 0x5f, 0x76, 0x62, 0x00, 0x3c, 0x92, + 0x53, 0x7f, 0xc0, 0xbd, 0xe9, 0x41, 0x18, 0x41, 0xe7, 0x47, 0x4c, 0xa8, 0xa7, 0x6d, 0xba, 0xda, + 0xb0, 0x61, 0x89, 0x81, 0x2e, 0x7c, 0x15, 0x40, 0xcc, 0x5a, 0x16, 0xcc, 0x4c, 0x45, 0x1a, 0xe2, + 0x65, 0xed, 0x0a, 0x0e, 0x23, 0x37, 0x58, 0xad, 0x96, 0x4d, 0xab, 0xf6, 0x08, 0x5f, 0xfb, 0xb2, + 0xff, 0x38, 0xfb, 0xd0, 0x20, 0xae, 0xfd, 0xa9, 0xc5, 0xab, 0x54, 0xca, 0x66, 0xd7, 0xfe, 0xe4, + 0x97, 0xc0, 0xbb, 0x34, 0x41, 0xf1, 0x3d, 0xf6, 0x87, 0xd9, 0x75, 0x23, 0x2a, 0x4c, 0x08, 0x61, + 0x57, 0x83, 0x15, 0x52, 0xa1, 0x42, 0xc4, 0x31, 0xba, 0xa5, 0x72, 0x57, 0x50, 0x7d, 0xf1, 0x6a, + 0x87, 0xbe, 0x6f, 0xbf, 0x57, 0x40, 0xea, 0xc1, 0x64, 0x75, 0x8e, 0x01, 0xd3, 0xeb, 0x5a, 0x46, + 0x03, 0x61, 0x67, 0x99, 0x3b, 0xe0, 0xdc, 0x60, 0xec, 0x0b, 0x05, 0xab, 0x96, 0x60, 0xbe, 0xb0, + 0xd2, 0xb5, 0xec, 0x97, 0xb4, 0x42, 0x1a, 0x77, 0xe0, 0x65, 0x4a, 0xef, 0x81, 0x29, 0xce, 0x24, + 0x71, 0x20, 0x5a, 0x18, 0x5f, 0x3a, 0x4e, 0x39, 0xfc, 0x3c, 0x65, 0xe0, 0xfe, 0x68, 0xdf, 0x24, + 0xba, 0x29, 0xfb, 0x5e, 0x57, 0xc8, 0xbd, 0x9c, 0x50, 0x4b, 0x6b, 0x73, 0x07, 0x20, 0xf7, 0xa7, + 0x6a, 0x2d, 0xdc, 0xe6, 0xfb, 0x65, 0xe8, 0x96, 0x64, 0xa8, 0xa3, 0xf9, 0xe2, 0xb2, 0xd3, 0x10, + 0x65, 0x03, 0xbd, 0x5f, 0xa4, 0xb7, 0x8a, 0xde, 0x6b, 0x86, 0x54, 0x9e, 0x1d, 0xdb, 0x06, 0x16, + 0xec, 0x57, 0x7c, 0xbf, 0xa2, 0xaa, 0x0b, 0x36, 0x0a, 0x6b, 0x55, 0xdc, 0xa0, 0x6b, 0x02, 0x80, + 0x6a, 0x9d, 0xb1, 0x4f, 0xce, 0x3f, 0x5c, 0x3a, 0xbb, 0x94, 0xb1, 0x28, 0x9b, 0x26, 0xa9, 0x67, + 0xbb, 0x8e, 0x06, 0xf1, 0x8b, 0x16, 0x1e, 0x68, 0xe2, 0xdb, 0xc7, 0x8d, 0x07, 0x77, 0x1a, 0xe6, + 0x0f, 0xa5, 0xe6, 0x08, 0x75, 0x37, 0xf1, 0x62, 0x92, 0x45, 0x49, 0x55, 0xeb, 0xd6, 0x45, 0x43, + 0xa9, 0x2f, 0x62, 0x1c, 0x33, 0x9e, 0x9e, 0x60, 0xa6, 0xf5, 0x9e, 0x51, 0xeb, 0x21, 0x96, 0xbf, + 0xee, 0xec, 0x19, 0x71, 0xb0, 0x3e, 0x01, 0x58, 0x6e, 0xd5, 0x1a, 0x3d, 0x04, 0x77, 0x33, 0x3b, + 0x70, 0xdb, 0x0f, 0x2f, 0x58, 0xb6, 0x41, 0x2c, 0xd9, 0xe2, 0xb4, 0xe2, 0xc5, 0x69, 0xd4, 0x33, + 0x63, 0xbd, 0xb1, 0x29, 0xa9, 0x29, 0xbe, 0xfe, 0xd3, 0x09, 0x0c, 0xbd, 0x9e, 0x05, 0x0e, 0x40, + 0x74, 0x6e, 0x9e, 0xf2, 0xa6, 0x27, 0x18, 0xe2, 0xb2, 0x5e, 0x79, 0x01, 0x21, 0xb7, 0x92, 0xba, + 0x5d, 0x27, 0x92, 0x6b, 0x56, 0x4d, 0x6d, 0x7b, 0xfc, 0x50, 0x14, 0x2e, 0x78, 0xdd, 0xa2, 0x07, + 0xe2, 0xc1, 0xb5, 0x23, 0x4d, 0x15, 0x27, 0xc4, 0x4a, 0x2d, 0xb3, 0x3d, 0x21, 0xc3, 0x37, 0x4d, + 0x62, 0x97, 0x51, 0x51, 0xe2, 0xc9, 0x59, 0xbc, 0x0d, 0xcd, 0x35, 0xba, 0x70, 0x64, 0xc9, 0xbe, + 0xf9, 0x8d, 0x99, 0x53, 0xdb, 0x7e, 0x08, 0xac, 0xab, 0x85, 0x5f, 0x20, 0xf2, 0x7d, 0xb2, 0xa9, + 0x4d, 0x5e, 0x35, 0x96, 0x95, 0xee, 0xad, 0x1a, 0x54, 0x45, 0x42, 0xae, 0x60, 0xc9, 0x23, 0x35, + 0xbb, 0xb1, 0xba, 0x2a, 0x56, 0x1d, 0xd2, 0x18, 0xb5, 0x35, 0xee, 0xe7, 0x8d, 0x0a, 0xe2, 0x0c, + 0xe4, 0x62, 0x70, 0x58, 0x23, 0xc6, 0xc4, 0x5f, 0x68, 0xe4, 0x15, 0x88, 0xa6, 0x60, 0x68, 0x4f, + 0xc1, 0xd0, 0xe4, 0xca, 0xce, 0xd0, 0x58, 0x6c, 0x4a, 0xf3, 0xb1, 0xe1, 0xb1, 0xe8, 0x08, 0xe9, + 0x4d, 0x3a, 0xe5, 0x3a, 0x95, 0x5c, 0xb3, 0x7e, 0x68, 0x8d, 0x3a, 0x94, 0x6e, 0xea, 0x69, 0x4d, + 0x11, 0xba, 0x48, 0x63, 0xc5, 0x49, 0x7a, 0x3d, 0x6f, 0x19, 0xc5, 0x29, 0x09, 0xaf, 0x3a, 0xc5, + 0xd4, 0xbc, 0x4d, 0x71, 0x9a, 0x9e, 0x5d, 0x7d, 0x55, 0xf8, 0x9b, 0xef, 0x9e, 0xd0, 0x08, 0xc7, + 0xd3, 0xc2, 0xe0, 0xf8, 0x24, 0xf6, 0x2e, 0xaa, 0x86, 0x51, 0xa8, 0xe2, 0x7e, 0x22, 0xdd, 0x01, + 0x1d, 0x8d, 0x2d, 0x45, 0x15, 0xb9, 0xb0, 0x41, 0xe6, 0x3b, 0xc9, 0x45, 0x72, 0x5b, 0xfc, 0x82, + 0xab, 0x95, 0x26, 0x83, 0x32, 0xd4, 0x98, 0x7a, 0x6b, 0x96, 0x0f, 0x91, 0x56, 0x6e, 0xef, 0x60, + 0x82, 0xf7, 0x1b, 0xcd, 0xf2, 0x4f, 0x39, 0xc4, 0xf0, 0x36, 0xbd, 0xc5, 0x17, 0x7f, 0x16, 0xa0, + 0xf5, 0x54, 0xb4, 0x1e, 0x4c, 0xfe, 0x84, 0x3a, 0xbf, 0x95, 0x5d, 0xb5, 0xf9, 0xbd, 0xd2, 0x23, + 0x55, 0x43, 0x14, 0xdb, 0x3c, 0x79, 0x35, 0x10, 0xbc, 0xe6, 0x28, 0xc5, 0xf6, 0x13, 0xbc, 0xe7, + 0x92, 0x2e, 0x7c, 0x2e, 0xdd, 0xeb, 0xcb, 0xfc, 0x63, 0x72, 0xdd, 0x77, 0x6a, 0x75, 0xdc, 0xa9, + 0x08, 0x55, 0xcf, 0x95, 0x77, 0xb1, 0x24, 0x05, 0x32, 0x6b, 0x7e, 0x4a, 0x5b, 0xbc, 0x36, 0xd7, + 0x8c, 0xaa, 0xf8, 0xd9, 0x3f, 0x50, 0x9d, 0x6e, 0xbb, 0x35, 0x52, 0xc6, 0x30, 0xd5, 0x57, 0x9d, + 0x9f, 0xdd, 0x65, 0xd9, 0x5f, 0xe5, 0x95, 0xd8, 0xe1, 0xcf, 0x69, 0xf3, 0xb8, 0x54, 0xdf, 0xe7, + 0xd4, 0xce, 0xfa, 0x3c, 0xa1, 0x1d, 0x5b, 0x41, 0xeb, 0xee, 0x13, 0xc2, 0xc8, 0x37, 0x76, 0x84, + 0xac, 0xcc, 0xa0, 0xce, 0xb5, 0xe6, 0xd8, 0x1c, 0x1b, 0xae, 0x9a, 0xa3, 0x3f, 0xb6, 0x51, 0x5a, + 0x18, 0xd4, 0xa5, 0x43, 0x75, 0x5f, 0x85, 0x33, 0x5c, 0xe6, 0x59, 0x29, 0x26, 0xa5, 0xde, 0xf1, + 0x28, 0xd8, 0x41, 0x70, 0xa2, 0x2e, 0x92, 0xcf, 0xd0, 0x58, 0xdd, 0x76, 0x2d, 0x8d, 0x67, 0xe4, + 0x27, 0x59, 0xa1, 0x5f, 0x8a, 0x8d, 0x4f, 0xa9, 0xaf, 0xf8, 0x8a, 0xbd, 0x45, 0xea, 0x93, 0x7a, + 0x72, 0x73, 0xcc, 0xf6, 0x07, 0x81, 0x5c, 0xca, 0x49, 0xea, 0x99, 0xc2, 0x84, 0xec, 0xa7, 0x90, + 0x7d, 0xe3, 0xcd, 0xf6, 0x25, 0xd8, 0xdd, 0x1f, 0x07, 0xd4, 0xd9, 0xbd, 0x4f, 0x78, 0xdd, 0xfe, + 0x01, 0x9e, 0xc7, 0x7e, 0x4f, 0xcd, 0x18, 0xc1, 0x1d, 0xd7, 0x32, 0xff, 0x93, 0xf4, 0xf2, 0xe4, + 0x5f, 0xe9, 0x99, 0x75, 0x6d, 0x55, 0x03, 0xb5, 0xd4, 0x5f, 0xe0, 0xc6, 0xe2, 0x7b, 0x77, 0xa0, + 0x48, 0x7a, 0x78, 0x00, 0xfe, 0x92, 0x6e, 0xf6, 0x32, 0xa9, 0x17, 0xcf, 0xe1, 0x4d, 0x4a, 0x3d, + 0x93, 0x72, 0x96, 0xca, 0x7d, 0x7c, 0x6b, 0xc5, 0xb3, 0x78, 0xa7, 0x34, 0xa7, 0x94, 0xa5, 0xdb, + 0x88, 0x39, 0xe0, 0xec, 0xd9, 0xfd, 0xa0, 0xe8, 0x76, 0x66, 0xa6, 0x86, 0x51, 0x1e, 0x8e, 0x42, + 0xfa, 0xcd, 0x51, 0x01, 0x54, 0x7b, 0xc8, 0x67, 0x42, 0x2a, 0x85, 0x58, 0xd5, 0x88, 0x95, 0xf1, + 0xc4, 0x76, 0x37, 0x8e, 0x03, 0x3f, 0x6c, 0x71, 0x7b, 0x34, 0x58, 0x42, 0x9b, 0xbc, 0x8f, 0x95, + 0x1d, 0xff, 0x61, 0xff, 0xb3, 0x85, 0x2e, 0xaa, 0x0c, 0xfa, 0xf0, 0x34, 0x19, 0xde, 0x64, 0x51, + 0x57, 0xe6, 0x74, 0xec, 0x32, 0xac, 0x25, 0xde, 0x83, 0xd5, 0x98, 0x43, 0xd8, 0xe5, 0x27, 0xd8, + 0xb9, 0x45, 0x31, 0x31, 0xea, 0xbc, 0xe4, 0x57, 0x17, 0x65, 0xf6, 0xe5, 0x02, 0x49, 0x8e, 0xd2, + 0x75, 0x66, 0x43, 0xad, 0x29, 0x91, 0x3b, 0x60, 0x9d, 0xcd, 0x1d, 0x38, 0x01, 0xa6, 0x8d, 0x6e, + 0x88, 0x8d, 0x3a, 0x9b, 0x00, 0xd1, 0xf8, 0x88, 0x01, 0x38, 0xe9, 0x6e, 0xdf, 0x9c, 0x61, 0x41, + 0x7e, 0x8a, 0x58, 0x8f, 0x4b, 0x61, 0xc6, 0x73, 0x2b, 0x89, 0xf5, 0x02, 0x5e, 0xcc, 0xe9, 0xe0, + 0xaa, 0xd7, 0x60, 0x80, 0x95, 0xa3, 0x10, 0x6b, 0x8b, 0x9c, 0xa3, 0x25, 0x56, 0x0f, 0x30, 0x8d, + 0xf7, 0xcb, 0x9a, 0x27, 0xc5, 0x9d, 0x5e, 0x3d, 0xcb, 0xb9, 0xd3, 0xd1, 0x57, 0x58, 0xe0, 0x45, + 0x97, 0xfc, 0x0a, 0x6e, 0xa7, 0xe4, 0x9f, 0x26, 0xc2, 0x61, 0x98, 0xf3, 0xb8, 0xdd, 0xc7, 0xe8, + 0x55, 0xef, 0x3a, 0x62, 0xfd, 0xb3, 0x34, 0x09, 0xe3, 0x26, 0xbe, 0x4b, 0xda, 0xa5, 0x65, 0x2f, + 0x91, 0xca, 0x6b, 0xd2, 0xd3, 0xba, 0x98, 0x06, 0x29, 0x6d, 0x40, 0x32, 0xb2, 0x8d, 0x44, 0xd8, + 0x2f, 0x3d, 0x7f, 0x47, 0xda, 0xa1, 0x89, 0xe9, 0x27, 0xd6, 0xb6, 0x94, 0x16, 0xd2, 0x33, 0xc5, + 0xda, 0xc5, 0xbd, 0xd1, 0x08, 0xc6, 0x6c, 0x09, 0x84, 0x83, 0xfc, 0x7e, 0x22, 0xb4, 0x93, 0xfc, + 0xe6, 0xf8, 0xeb, 0x78, 0xe0, 0xe7, 0xf5, 0x7a, 0x43, 0x8f, 0x6b, 0x90, 0x15, 0xee, 0x5d, 0x02, + 0xa6, 0x60, 0x28, 0xfe, 0x7a, 0xc5, 0x78, 0xa8, 0x43, 0x86, 0xa6, 0x08, 0xcd, 0xdc, 0xee, 0xbf, + 0x03, 0x9e, 0xc1, 0x6c, 0x68, 0x5e, 0x7d, 0x0e, 0xdc, 0x7b, 0xa1, 0x19, 0x1a, 0x4b, 0xc2, 0x35, + 0x22, 0x00, 0x2c, 0x05, 0xeb, 0xb5, 0x03, 0x88, 0xea, 0x8b, 0x42, 0xa4, 0xc4, 0xb7, 0xa1, 0xa2, + 0x08, 0x87, 0xc9, 0x2e, 0x0d, 0xb8, 0xe8, 0x56, 0x05, 0x57, 0xce, 0xda, 0xe3, 0x07, 0x88, 0x0d, + 0xdc, 0x5b, 0x70, 0xbd, 0x4e, 0x4b, 0x80, 0x35, 0x5f, 0x27, 0x7a, 0xe3, 0x96, 0x73, 0xea, 0x05, + 0xef, 0x2c, 0xad, 0xb4, 0x5a, 0x47, 0xea, 0xa3, 0x4e, 0x3a, 0xd7, 0xd1, 0x75, 0xd2, 0x95, 0xcb, + 0x90, 0xc7, 0xe4, 0xa4, 0x78, 0x85, 0xa9, 0xc8, 0x92, 0x26, 0xa1, 0xd3, 0xd2, 0x4f, 0x2e, 0x56, + 0x35, 0x52, 0xf7, 0x23, 0x0f, 0x9c, 0x18, 0x05, 0xd8, 0xfe, 0x29, 0x0a, 0xd9, 0x8c, 0xeb, 0xe1, + 0x7c, 0xd7, 0x44, 0x93, 0x02, 0x50, 0xc9, 0x23, 0x49, 0x7e, 0x92, 0xa7, 0x01, 0xfe, 0xaf, 0xd1, + 0x1d, 0xa2, 0x65, 0xcd, 0x24, 0x5b, 0x8b, 0x37, 0x7d, 0x79, 0xbf, 0x2f, 0x01, 0xcf, 0x6a, 0x69, + 0x56, 0x48, 0xd6, 0x16, 0xf0, 0x0f, 0x16, 0xd4, 0x93, 0xe6, 0x43, 0xe8, 0xfb, 0xf5, 0x7e, 0xb0, + 0xfc, 0x71, 0xa8, 0x90, 0x91, 0xd2, 0xc0, 0xed, 0x16, 0xf1, 0xe4, 0x13, 0x38, 0x04, 0x87, 0x29, + 0x65, 0xfd, 0x46, 0x8f, 0x9c, 0x90, 0x2a, 0xee, 0xbc, 0x8c, 0x6c, 0xc0, 0x0b, 0xa0, 0xf2, 0xd2, + 0xcb, 0xd2, 0xbd, 0xd2, 0x36, 0xcd, 0x21, 0x3a, 0x97, 0x5a, 0x95, 0x94, 0x56, 0x55, 0xda, 0xba, + 0xa5, 0x35, 0x5a, 0x29, 0x4f, 0x07, 0x28, 0x56, 0x64, 0x90, 0x93, 0xe1, 0x26, 0x65, 0xa2, 0xd0, + 0x55, 0x75, 0x8b, 0x45, 0x11, 0xbd, 0xce, 0x54, 0x3c, 0x02, 0xb3, 0x7f, 0xd5, 0x09, 0x44, 0x86, + 0x05, 0xab, 0xd8, 0x21, 0xaf, 0xba, 0xac, 0x45, 0xc3, 0xdb, 0x25, 0x9e, 0x0b, 0x10, 0x23, 0xc9, + 0xd1, 0x34, 0x65, 0xd3, 0x0d, 0xf5, 0xa6, 0x31, 0x74, 0xbc, 0xdd, 0xbe, 0x70, 0x28, 0x8b, 0x6a, + 0x15, 0xe2, 0x24, 0xab, 0x5f, 0xd6, 0xe5, 0x4a, 0x42, 0x8b, 0xbc, 0xe0, 0x4c, 0x10, 0x53, 0x90, + 0x1a, 0xff, 0x72, 0x80, 0x91, 0xba, 0x84, 0xf7, 0x73, 0xbb, 0xd7, 0xd3, 0x88, 0xd7, 0x4f, 0xea, + 0x51, 0x98, 0x84, 0x71, 0xf4, 0x76, 0x90, 0xbf, 0xf3, 0x51, 0x7a, 0x70, 0x1d, 0xdd, 0x2f, 0xd3, + 0x35, 0xd2, 0x6c, 0x3c, 0x01, 0x1e, 0x9d, 0x6e, 0x85, 0xac, 0x69, 0x26, 0x78, 0xc6, 0xda, 0x9f, + 0x72, 0x12, 0x6f, 0x6f, 0xb5, 0x38, 0x52, 0x90, 0x41, 0x7a, 0xa9, 0x5c, 0xa3, 0x5e, 0x4a, 0x26, + 0x0d, 0x28, 0x3d, 0x63, 0x70, 0xbb, 0x76, 0x8d, 0x06, 0x64, 0xa4, 0x39, 0x1e, 0xbf, 0xab, 0xc1, + 0xa5, 0x77, 0xe3, 0xd9, 0x98, 0x74, 0xab, 0xc2, 0xa5, 0x37, 0x64, 0x88, 0x4d, 0x71, 0x29, 0x97, + 0x85, 0x4b, 0xb2, 0x2e, 0x15, 0x3c, 0x2b, 0x39, 0x56, 0xa5, 0x9e, 0x9c, 0xff, 0x36, 0xf9, 0x8c, + 0x5c, 0xec, 0xfd, 0x80, 0xa6, 0x70, 0x9e, 0x6c, 0x1b, 0x91, 0x22, 0xd7, 0x7b, 0x3f, 0x90, 0x4c, + 0xed, 0x69, 0x22, 0x7f, 0x2d, 0x6e, 0x89, 0xe9, 0x02, 0xe7, 0x2e, 0xc3, 0xcd, 0x48, 0x4f, 0x32, + 0xde, 0x19, 0xf2, 0x20, 0x20, 0x6b, 0x87, 0xe4, 0x3c, 0xa9, 0xaf, 0x1a, 0xc2, 0xa1, 0x43, 0x88, + 0x3d, 0xc4, 0x0a, 0x65, 0x52, 0x25, 0x00, 0x3f, 0x9b, 0x52, 0x31, 0x5b, 0x28, 0x94, 0x9c, 0x67, + 0xb5, 0xd2, 0x53, 0x67, 0x75, 0x78, 0xd0, 0x7c, 0x32, 0xc8, 0x18, 0xdb, 0x2b, 0x55, 0x68, 0x80, + 0xb6, 0xf3, 0x2b, 0x12, 0xe6, 0x3f, 0x11, 0x17, 0xd5, 0x2b, 0xa4, 0x83, 0x1f, 0x1a, 0x5e, 0x61, + 0x00, 0xc9, 0x9d, 0xf8, 0x44, 0xa2, 0xbc, 0xf6, 0xac, 0x96, 0x3c, 0xa1, 0x21, 0x0f, 0xc9, 0xe6, + 0x30, 0x29, 0xdf, 0x9f, 0x72, 0xc5, 0x31, 0x35, 0xa9, 0x41, 0x6c, 0x18, 0x92, 0xac, 0xed, 0x72, + 0xec, 0x49, 0xf9, 0x05, 0x45, 0x45, 0x0a, 0xb0, 0x13, 0xeb, 0xe3, 0x1e, 0x17, 0xbe, 0x01, 0x42, + 0x5e, 0x00, 0x62, 0x9b, 0xfc, 0xa9, 0x30, 0xcf, 0x81, 0xcb, 0x7b, 0x21, 0x05, 0x84, 0x7c, 0x23, + 0xa5, 0xe9, 0x71, 0xbc, 0x72, 0xad, 0x0d, 0x2d, 0x7a, 0xda, 0x17, 0xae, 0xa1, 0xe6, 0xe3, 0xd3, + 0xaf, 0xa8, 0x4b, 0x80, 0xe7, 0x3c, 0x86, 0x6d, 0x45, 0x29, 0x1b, 0x5a, 0x38, 0x79, 0x0f, 0x93, + 0x24, 0xb2, 0x31, 0x02, 0xcd, 0x21, 0x5b, 0x87, 0x35, 0x46, 0x9c, 0x3b, 0xd2, 0x89, 0xcb, 0x9c, + 0x16, 0xea, 0xe6, 0xbc, 0x4e, 0xd7, 0x4b, 0xea, 0xb6, 0x43, 0x4a, 0x9a, 0x4a, 0xdb, 0x80, 0x7c, + 0xdc, 0xc6, 0x93, 0xce, 0x5c, 0xf5, 0x35, 0x7a, 0xb4, 0xfc, 0x7f, 0xe8, 0x37, 0xbd, 0xde, 0x5c, + 0x81, 0x20, 0x42, 0x94, 0x6c, 0x04, 0x4a, 0xbe, 0xa0, 0x91, 0xa2, 0xa5, 0x0a, 0x2d, 0xde, 0xef, + 0xf6, 0x4b, 0x15, 0xba, 0x98, 0x21, 0xf1, 0x05, 0x14, 0x4d, 0xdc, 0x06, 0xfa, 0x04, 0x97, 0xa3, + 0x8a, 0xa5, 0x09, 0xdc, 0xb1, 0x73, 0xdc, 0xc1, 0x2b, 0xde, 0x2f, 0x34, 0x55, 0x83, 0xcc, 0xbb, + 0x81, 0xc0, 0x27, 0xf8, 0x95, 0x23, 0xce, 0x74, 0x25, 0xe5, 0x32, 0x1e, 0x2d, 0x5f, 0xaf, 0xf6, + 0x27, 0xc7, 0xd2, 0x0e, 0xa4, 0x57, 0x73, 0xb1, 0x83, 0x63, 0xe8, 0x4b, 0xa6, 0x9c, 0xa5, 0x33, + 0xe3, 0x94, 0xc3, 0xb9, 0x1a, 0xc8, 0xaa, 0x58, 0x58, 0x55, 0xe9, 0x67, 0x81, 0x27, 0xa4, 0x1f, + 0x9a, 0x49, 0x95, 0x0a, 0xb7, 0xfb, 0x14, 0xc5, 0x88, 0x36, 0x00, 0x59, 0x06, 0x61, 0x66, 0x57, + 0x6a, 0xc5, 0x5c, 0x5d, 0xa0, 0x29, 0x5d, 0x15, 0xde, 0x30, 0xb4, 0xbe, 0x87, 0x54, 0x24, 0xa2, + 0xb8, 0x63, 0xad, 0xdc, 0xc1, 0x93, 0xde, 0x1b, 0xa3, 0x91, 0x38, 0xf9, 0x09, 0xd6, 0x01, 0xdf, + 0x25, 0x65, 0x90, 0x7e, 0xa5, 0x24, 0xbe, 0xa7, 0xc2, 0x1e, 0x74, 0x7f, 0xe2, 0xbb, 0x1d, 0xf9, + 0xc3, 0x8d, 0x4f, 0x70, 0x07, 0x5b, 0xbd, 0x9f, 0x6b, 0xaa, 0x6e, 0x61, 0xe3, 0x43, 0x6a, 0xe3, + 0xd6, 0x20, 0xea, 0x2a, 0x6d, 0xd0, 0x17, 0x38, 0xbc, 0x42, 0x0b, 0xc8, 0x3c, 0x88, 0x9f, 0x18, + 0xea, 0x92, 0x5e, 0x5d, 0xa1, 0x83, 0x44, 0x7c, 0x37, 0x7b, 0x09, 0xaf, 0x10, 0x1c, 0xce, 0xc5, + 0x22, 0xfc, 0x5a, 0xd2, 0xab, 0xb9, 0x98, 0xef, 0x8b, 0x54, 0x5b, 0x67, 0x10, 0xfa, 0x03, 0x03, + 0xca, 0x16, 0x3d, 0x71, 0x4b, 0x28, 0x43, 0xc8, 0x2d, 0x6e, 0xf7, 0x8b, 0x74, 0x4d, 0x67, 0x98, + 0xa7, 0x36, 0xc5, 0x44, 0x57, 0x02, 0x35, 0xd4, 0x84, 0xd4, 0xfd, 0xdb, 0x4e, 0x0d, 0x33, 0xa3, + 0x99, 0x6d, 0x3e, 0x84, 0x52, 0x6a, 0xb3, 0x95, 0xb2, 0xb6, 0x1c, 0x9b, 0xd9, 0x96, 0x33, 0xc2, + 0xcc, 0xcb, 0xf4, 0x38, 0xc0, 0x9c, 0x91, 0x10, 0xc6, 0xaa, 0x10, 0x54, 0x69, 0x60, 0x42, 0xa7, + 0x43, 0xec, 0x6f, 0xaa, 0xcb, 0xfb, 0xe5, 0x7f, 0xa3, 0xa2, 0x84, 0x1b, 0xd9, 0xe3, 0x28, 0x16, + 0x5a, 0x2a, 0x0f, 0x54, 0x5c, 0x82, 0xf3, 0xa9, 0x60, 0x94, 0x78, 0x5d, 0x04, 0x5a, 0x9a, 0x59, + 0x88, 0x05, 0x5e, 0xe4, 0x3f, 0x97, 0x93, 0x9b, 0x9b, 0x9b, 0x93, 0x6b, 0xce, 0x1d, 0x3d, 0xc9, + 0x70, 0x61, 0xc1, 0x49, 0x86, 0xce, 0x53, 0x78, 0xff, 0x5b, 0x85, 0x4e, 0xef, 0x59, 0x95, 0x32, + 0x66, 0xba, 0x7f, 0x3f, 0x75, 0xc4, 0x39, 0x21, 0xdc, 0xfb, 0xd1, 0xff, 0xab, 0xf3, 0x43, 0x71, + 0xb8, 0x67, 0x04, 0xb1, 0x73, 0xa6, 0x16, 0xd7, 0xa6, 0xf0, 0xf3, 0x3d, 0x77, 0x27, 0xf8, 0x21, + 0x7a, 0x09, 0x9e, 0x8a, 0x6c, 0xf3, 0xf2, 0xed, 0x2f, 0x24, 0x59, 0xd1, 0x9c, 0xca, 0x0b, 0xfe, + 0x7b, 0x00, 0x77, 0xc9, 0x1e, 0x65, 0x85, 0x67, 0xa4, 0x2c, 0xbf, 0x64, 0xbb, 0x29, 0xed, 0x1a, + 0x00, 0xf7, 0x8c, 0x6d, 0x92, 0x9e, 0xbe, 0x13, 0x73, 0xde, 0x7d, 0x75, 0x57, 0x8c, 0xab, 0x32, + 0x96, 0x11, 0xc6, 0x1a, 0x03, 0xee, 0x73, 0x9f, 0xe2, 0x32, 0xef, 0x4b, 0x8b, 0xf0, 0x0b, 0x1f, + 0x95, 0x1d, 0xc0, 0x3b, 0xf1, 0x2a, 0x43, 0x91, 0xb1, 0xe4, 0x11, 0x53, 0x3b, 0x9e, 0xbf, 0xee, + 0xfb, 0x33, 0xe8, 0x9f, 0xa9, 0x1d, 0x30, 0x02, 0x5f, 0xfa, 0x3c, 0xd8, 0x87, 0x25, 0x95, 0xd7, + 0x48, 0xdb, 0x14, 0x30, 0x4e, 0xbc, 0x52, 0x19, 0xbb, 0x42, 0x6c, 0x54, 0xdc, 0x27, 0x5e, 0x7a, + 0xc3, 0x9e, 0xa1, 0xde, 0x35, 0x48, 0xea, 0x08, 0x04, 0x92, 0x06, 0xe3, 0xdb, 0x48, 0xa3, 0xd1, + 0x03, 0x04, 0x32, 0x9b, 0x73, 0xf0, 0xb8, 0x94, 0x2d, 0xd7, 0x92, 0x37, 0x82, 0x3c, 0x7e, 0x3a, + 0xc2, 0x39, 0x88, 0x84, 0x73, 0x22, 0x59, 0x86, 0xc8, 0x92, 0xa9, 0x77, 0xe0, 0xef, 0x31, 0x7c, + 0xf5, 0x8d, 0x0f, 0xe0, 0xfd, 0xac, 0x3c, 0xe5, 0x01, 0xf5, 0x2c, 0xe8, 0x08, 0xcd, 0x66, 0x82, + 0xeb, 0x75, 0x1a, 0xbc, 0xd2, 0x1c, 0x37, 0xc2, 0x13, 0x70, 0x8f, 0xf8, 0x42, 0x94, 0x16, 0x0f, + 0xa5, 0x9f, 0x23, 0x66, 0x0d, 0xc1, 0x4d, 0xf4, 0x17, 0x25, 0xab, 0x5e, 0xac, 0xd7, 0x07, 0xd7, + 0xc4, 0x42, 0x37, 0x69, 0x17, 0xb3, 0x82, 0x59, 0x4a, 0xf7, 0x4b, 0x2f, 0xdc, 0x3c, 0x4a, 0x95, + 0x2d, 0xb8, 0xc9, 0x3d, 0x24, 0x3d, 0x31, 0x50, 0x31, 0x8f, 0x5c, 0x67, 0x1b, 0x27, 0xbe, 0x70, + 0xa7, 0x6a, 0x08, 0x15, 0x0e, 0xb5, 0x74, 0x26, 0x38, 0x61, 0x49, 0x8d, 0xe3, 0x50, 0xc9, 0xc0, + 0xcf, 0x41, 0x2d, 0x14, 0xfc, 0xe1, 0xf9, 0x5d, 0x6c, 0x03, 0x98, 0x41, 0x9f, 0x96, 0x85, 0x3f, + 0xe1, 0x6c, 0x3e, 0xc4, 0x95, 0x71, 0x2b, 0x84, 0x0f, 0x68, 0xff, 0x7e, 0xb2, 0x5c, 0x83, 0x62, + 0xaf, 0x0f, 0xfa, 0x65, 0xf5, 0x1a, 0x66, 0xf8, 0x13, 0x43, 0x42, 0x02, 0x7e, 0xb2, 0x86, 0xd7, + 0x49, 0x7a, 0x3c, 0x17, 0xde, 0x1c, 0xe5, 0xe7, 0xaa, 0xff, 0x17, 0xc3, 0x5d, 0x7e, 0xce, 0x4c, + 0x3e, 0x59, 0xfd, 0x62, 0x53, 0xb8, 0x49, 0x8f, 0x87, 0x1c, 0x85, 0x58, 0x22, 0x74, 0xe1, 0xb9, + 0x5f, 0xad, 0xf3, 0x19, 0x89, 0x4f, 0x94, 0x1d, 0x7a, 0x70, 0x2e, 0x35, 0x29, 0x91, 0xc2, 0x2a, + 0x3c, 0xa9, 0xb2, 0xcb, 0x2f, 0x3d, 0x7d, 0x53, 0xca, 0x1a, 0x60, 0x07, 0xa4, 0xd5, 0x77, 0x62, + 0x2e, 0xc3, 0x38, 0x53, 0x06, 0x25, 0x6b, 0x2c, 0xb9, 0x14, 0xff, 0x19, 0xf7, 0x7a, 0x43, 0x0a, + 0xaf, 0x8f, 0x3f, 0xc9, 0xbd, 0xd1, 0x04, 0x5e, 0x00, 0x84, 0x32, 0xdc, 0xeb, 0x1e, 0x6d, 0x9b, + 0x76, 0x40, 0x88, 0x74, 0x55, 0xce, 0x81, 0x89, 0xbc, 0x1a, 0x0f, 0x7b, 0xa1, 0xa9, 0xe7, 0x13, + 0x9d, 0x4e, 0xb1, 0x31, 0x6e, 0xa5, 0xf0, 0x2b, 0x57, 0xe5, 0x6c, 0xc6, 0x09, 0xc5, 0xc9, 0x8c, + 0x73, 0x13, 0xfe, 0x95, 0x04, 0x9d, 0x73, 0x9a, 0x0c, 0x08, 0x5e, 0x0e, 0x08, 0x86, 0x91, 0x1e, + 0x95, 0x62, 0x53, 0x8f, 0x7a, 0xfa, 0xee, 0x37, 0x7a, 0x7c, 0x29, 0x50, 0x03, 0x40, 0xfd, 0x63, + 0x25, 0xa3, 0x5a, 0x09, 0x37, 0x77, 0x2b, 0xfd, 0x78, 0x2c, 0x1c, 0x78, 0x57, 0x4b, 0xbf, 0x56, + 0xa3, 0x81, 0x49, 0x2d, 0x72, 0x3f, 0x1b, 0x3a, 0x54, 0x6a, 0xcf, 0xce, 0xa1, 0x82, 0xe3, 0xbf, + 0x31, 0x1c, 0xdd, 0x2d, 0x92, 0x78, 0x7d, 0x38, 0x5e, 0x6b, 0x52, 0x24, 0x3e, 0x76, 0x22, 0xaf, + 0xc3, 0x99, 0x70, 0x32, 0x7e, 0x9b, 0xeb, 0xa7, 0xb8, 0xf0, 0x60, 0xf5, 0xc8, 0x69, 0x10, 0xf5, + 0x1d, 0x36, 0xa2, 0xb3, 0x86, 0x9f, 0x8d, 0xe1, 0xdb, 0x65, 0x0d, 0x4c, 0xb4, 0xc7, 0xe5, 0xa5, + 0x5e, 0x69, 0x8c, 0xb4, 0x4d, 0x4b, 0x84, 0xd3, 0x6c, 0x23, 0xcc, 0x9a, 0xd4, 0x01, 0x68, 0x8e, + 0x39, 0xb9, 0x04, 0x40, 0x9d, 0x9a, 0x92, 0xaf, 0xab, 0xf8, 0x41, 0x8a, 0x00, 0x2e, 0x49, 0x57, + 0xfc, 0x79, 0x9c, 0xa0, 0xda, 0xc0, 0xa1, 0x93, 0x4c, 0x87, 0xc1, 0x91, 0x0b, 0x4e, 0xe5, 0x8f, + 0xc3, 0xac, 0x8b, 0x53, 0x79, 0xe7, 0x3b, 0x34, 0x5c, 0x04, 0x17, 0xaa, 0x25, 0xd4, 0x92, 0x7b, + 0x83, 0xef, 0x45, 0x77, 0x0a, 0xde, 0xbb, 0xf0, 0xa2, 0x9d, 0xf5, 0xb8, 0xbc, 0xf6, 0x3c, 0x78, + 0x86, 0x17, 0x1c, 0xf3, 0x5d, 0x95, 0xbd, 0x78, 0x63, 0x5f, 0x68, 0x51, 0x61, 0x4f, 0xc9, 0xbf, + 0xe6, 0x98, 0x0e, 0x73, 0x20, 0x79, 0x04, 0xcf, 0x9e, 0xaf, 0xd7, 0x24, 0xf9, 0xe3, 0x2f, 0x87, + 0xf3, 0xa7, 0x27, 0x9a, 0x9a, 0x25, 0xeb, 0x05, 0x12, 0x46, 0x56, 0x6a, 0x7c, 0x8b, 0xc0, 0xdd, + 0x49, 0xc1, 0x93, 0xa3, 0xe0, 0xad, 0x5d, 0x8b, 0xef, 0xe7, 0xde, 0x68, 0xd0, 0xe6, 0xf7, 0x0a, + 0x0b, 0x53, 0xac, 0x0a, 0xf8, 0x67, 0xf1, 0xfd, 0x15, 0x73, 0x24, 0xd3, 0xe9, 0x70, 0x13, 0x08, + 0x72, 0x33, 0x0c, 0x3d, 0xa9, 0x15, 0xe6, 0x7d, 0x68, 0x19, 0x4d, 0xd2, 0x35, 0xe8, 0x34, 0xe1, + 0x95, 0xee, 0xf6, 0xd4, 0x94, 0x36, 0x6e, 0x77, 0x18, 0x9e, 0x50, 0x7a, 0x1e, 0x30, 0x9c, 0x62, + 0x02, 0xef, 0xad, 0xcd, 0x51, 0x40, 0xba, 0x83, 0x58, 0xf0, 0x5d, 0xf1, 0xcd, 0x50, 0xd7, 0xf1, + 0x57, 0xa9, 0xf2, 0x82, 0x64, 0x3d, 0x1d, 0x6e, 0x0d, 0xc1, 0xea, 0x21, 0xf7, 0x4e, 0x01, 0xe7, + 0x31, 0x5b, 0xa3, 0x4e, 0x6e, 0x8e, 0x47, 0x91, 0x04, 0xe0, 0xfd, 0xee, 0x6c, 0xd5, 0x13, 0x70, + 0x6d, 0x33, 0x50, 0x64, 0xd7, 0x7a, 0x35, 0x78, 0xd7, 0x6b, 0xa9, 0x37, 0x09, 0xa6, 0xe9, 0x6b, + 0x53, 0x68, 0x8e, 0x8e, 0x38, 0xbd, 0x5a, 0xdf, 0xcb, 0x00, 0xd3, 0x57, 0x55, 0x75, 0x3b, 0x40, + 0x2f, 0x83, 0x78, 0xb6, 0x8e, 0x0f, 0x99, 0xce, 0x87, 0xdb, 0xd1, 0x89, 0x97, 0xf8, 0x38, 0x79, + 0xc1, 0x93, 0x24, 0xb3, 0x5b, 0x8f, 0x5b, 0x1f, 0x99, 0xdd, 0x1a, 0x3c, 0x34, 0xa4, 0xe9, 0x06, + 0x0e, 0x42, 0x42, 0x07, 0x1c, 0x85, 0x1f, 0x6d, 0x06, 0x99, 0x1c, 0x5a, 0x6d, 0x40, 0xab, 0x57, + 0xae, 0x7c, 0x15, 0x34, 0xca, 0xa9, 0xe3, 0x58, 0xf5, 0x3c, 0x80, 0xd8, 0x35, 0x5b, 0x16, 0x2e, + 0xe0, 0xca, 0x80, 0x4d, 0xb9, 0x3f, 0x52, 0xfd, 0x5e, 0x49, 0x56, 0xa2, 0xd9, 0x46, 0xed, 0xfc, + 0x64, 0x65, 0xf5, 0x47, 0x74, 0x45, 0x80, 0x3b, 0x98, 0x95, 0xb8, 0x6c, 0x35, 0x64, 0x0a, 0x02, + 0x77, 0x10, 0xaf, 0xf7, 0x68, 0xb8, 0x83, 0xc2, 0x4d, 0xb6, 0xb1, 0x34, 0xd2, 0xfe, 0x5b, 0x7a, + 0x84, 0xef, 0x81, 0xc8, 0xe0, 0x8a, 0xaa, 0xf0, 0x24, 0xd4, 0x8d, 0x5c, 0x86, 0xe3, 0xdd, 0x9a, + 0x27, 0x65, 0xcd, 0xe6, 0x0e, 0xfa, 0xbd, 0x8a, 0x4e, 0x6c, 0xf7, 0x43, 0x65, 0x8d, 0xfd, 0x59, + 0xba, 0xad, 0x38, 0x18, 0x11, 0xaa, 0xbc, 0x14, 0x0f, 0x88, 0xae, 0xdc, 0x47, 0x71, 0x72, 0x2d, + 0x7b, 0x87, 0xae, 0xb2, 0x8c, 0xb3, 0xf3, 0xf8, 0xf9, 0x87, 0xc5, 0xea, 0xa2, 0xb1, 0x78, 0x7c, + 0x36, 0xf8, 0x10, 0xf6, 0x07, 0x20, 0xcb, 0x37, 0xd1, 0x8e, 0xd7, 0x02, 0x7d, 0x3a, 0xbb, 0xb2, + 0x8a, 0xde, 0xb7, 0x2a, 0x50, 0x4f, 0x47, 0xcd, 0xfa, 0x2c, 0x24, 0xca, 0x55, 0x5d, 0xdb, 0x91, + 0x58, 0x82, 0xce, 0xdd, 0xe7, 0xfc, 0xa1, 0x4d, 0x59, 0x7f, 0x2d, 0xb4, 0x62, 0x6f, 0x08, 0xee, + 0x3f, 0xd8, 0x94, 0x67, 0xae, 0x05, 0x17, 0x6b, 0x39, 0xf7, 0x7d, 0xb8, 0xc7, 0xf3, 0x0e, 0xe6, + 0xfb, 0xec, 0x78, 0xd1, 0x91, 0x6e, 0x3d, 0x44, 0xe2, 0x9d, 0x9c, 0x2c, 0x4d, 0x71, 0x53, 0x56, + 0x58, 0x38, 0x43, 0x00, 0x77, 0x0d, 0xe9, 0x16, 0x6f, 0xe8, 0x8e, 0xe1, 0x76, 0xdc, 0x8c, 0x81, + 0x1c, 0x73, 0xe9, 0xf3, 0xca, 0xde, 0xff, 0xa2, 0x34, 0x91, 0xb6, 0x46, 0x92, 0xe0, 0xd8, 0x66, + 0x0c, 0x41, 0xd8, 0xbe, 0xac, 0x1c, 0xbd, 0x1b, 0x61, 0xb2, 0x7d, 0x36, 0xbd, 0xba, 0xb8, 0x3c, + 0x17, 0x2c, 0xef, 0x31, 0x8d, 0x7a, 0x54, 0x2d, 0x02, 0xcb, 0x58, 0xe9, 0xe9, 0x58, 0xf9, 0x63, + 0xfc, 0xaa, 0x54, 0xe9, 0x43, 0x48, 0xee, 0x83, 0x9a, 0xe0, 0x67, 0xb3, 0xa0, 0x13, 0xf1, 0xcb, + 0xf1, 0xdc, 0x41, 0x8f, 0xcd, 0x5c, 0xaa, 0x53, 0x78, 0x15, 0x3c, 0xae, 0x96, 0x73, 0xee, 0x62, + 0xf5, 0x0b, 0x53, 0x7a, 0xba, 0x4f, 0xd2, 0xa5, 0xe2, 0x68, 0xdf, 0x83, 0x87, 0x50, 0x00, 0xc0, + 0xd6, 0x20, 0x80, 0xa7, 0xc3, 0x64, 0x77, 0x16, 0x6e, 0xa5, 0x08, 0x7a, 0xb3, 0x62, 0xbd, 0x42, + 0x07, 0x18, 0x84, 0xca, 0xa9, 0x50, 0x67, 0x29, 0xdf, 0x7e, 0x34, 0x02, 0xaa, 0x1e, 0xe7, 0x4b, + 0xbe, 0xab, 0xa5, 0x34, 0x59, 0xb9, 0x18, 0x34, 0xf0, 0x8d, 0x12, 0xdf, 0x68, 0x0c, 0x90, 0x5d, + 0x06, 0x92, 0x95, 0xb0, 0x9f, 0xad, 0x89, 0xac, 0xc9, 0x4a, 0x24, 0x4f, 0xcf, 0x06, 0x32, 0xcc, + 0xe1, 0x19, 0x10, 0x26, 0xb3, 0x32, 0xe1, 0xaa, 0x5a, 0x11, 0xd4, 0x32, 0xdf, 0x2f, 0xaf, 0x0b, + 0xb3, 0x28, 0xff, 0x1e, 0x6c, 0x9a, 0xa5, 0x6d, 0x64, 0xe6, 0x41, 0xf4, 0x92, 0x1a, 0x10, 0x14, + 0x8a, 0xc2, 0x89, 0xf0, 0x20, 0x5e, 0xba, 0xba, 0x5a, 0xf4, 0x9a, 0xde, 0xd9, 0x89, 0x5b, 0x40, + 0x79, 0x96, 0xe0, 0x41, 0x4f, 0x7a, 0x4a, 0x32, 0x23, 0xac, 0xb8, 0x49, 0xc4, 0x52, 0x86, 0x07, + 0x05, 0x2a, 0x26, 0xe2, 0xab, 0x58, 0xd3, 0xfd, 0xf2, 0x50, 0x70, 0x18, 0x7b, 0x2e, 0xab, 0xc3, + 0x68, 0xc3, 0x61, 0x7c, 0x81, 0xc4, 0xb1, 0x98, 0x4b, 0x0d, 0xca, 0xec, 0x8f, 0x42, 0x1b, 0xa7, + 0xb3, 0x80, 0x2c, 0x14, 0xae, 0xfd, 0x2f, 0x78, 0x34, 0x64, 0x6c, 0x27, 0xad, 0x8f, 0xc7, 0x89, + 0x3f, 0x51, 0xcf, 0x28, 0x77, 0xfe, 0x40, 0xbd, 0x92, 0xa6, 0xa5, 0xb4, 0x53, 0xcc, 0xca, 0x9a, + 0xe0, 0x6a, 0x2f, 0xef, 0x0f, 0x6c, 0x4d, 0x50, 0xfe, 0xa7, 0x3f, 0x88, 0xbd, 0x5e, 0xca, 0x4a, + 0x18, 0x9b, 0x65, 0xe0, 0xaa, 0x9b, 0xe8, 0xc9, 0x3b, 0x3f, 0xf1, 0x8a, 0x37, 0x38, 0x62, 0x3a, + 0x8d, 0xac, 0xe7, 0x5b, 0x64, 0xfe, 0x3a, 0x3d, 0xa9, 0x2d, 0xb6, 0x8f, 0x0f, 0x4e, 0x66, 0x80, + 0x0a, 0xe1, 0x2f, 0x70, 0x07, 0xbd, 0x10, 0x4f, 0x18, 0x03, 0x4d, 0xfc, 0x75, 0xcc, 0x2c, 0x6e, + 0xe2, 0x3f, 0xc7, 0xd6, 0xa7, 0x8b, 0xf1, 0x6e, 0x19, 0xdf, 0x02, 0x3f, 0x5f, 0xe2, 0xc7, 0x0f, + 0x84, 0xb6, 0xd2, 0x99, 0x8a, 0xe3, 0xf7, 0xa1, 0xb3, 0x3e, 0xee, 0xf7, 0xb1, 0x8f, 0x2c, 0x3d, + 0x3b, 0xc0, 0x1d, 0x34, 0x7d, 0x9e, 0x43, 0x3f, 0x71, 0xf3, 0xef, 0x61, 0xc1, 0x7b, 0x99, 0xd6, + 0xcf, 0xd9, 0x4b, 0xc5, 0x4b, 0xc0, 0x2c, 0xd1, 0xcf, 0xaa, 0x38, 0xe6, 0x80, 0x45, 0x73, 0x7d, + 0xc1, 0x0a, 0x89, 0x29, 0x4d, 0xea, 0xd1, 0xf9, 0x53, 0x8e, 0xf8, 0x5c, 0x7b, 0x21, 0xea, 0xc6, + 0x34, 0xf5, 0x84, 0xb6, 0x5a, 0x91, 0x7e, 0x8a, 0x29, 0xa5, 0x89, 0xee, 0x28, 0xc6, 0x83, 0x03, + 0x5f, 0x8a, 0xbb, 0xad, 0xfc, 0xf5, 0xe2, 0x26, 0x7a, 0xcf, 0x50, 0x45, 0x9d, 0x3b, 0x78, 0xc2, + 0x9c, 0x53, 0x3a, 0x43, 0xe9, 0xfc, 0x5d, 0x10, 0x13, 0x61, 0x21, 0x65, 0x96, 0x5f, 0x91, 0xfb, + 0x54, 0x3a, 0xf7, 0xe3, 0x56, 0xcb, 0xf6, 0xbb, 0xdf, 0xd1, 0x79, 0x41, 0x55, 0xad, 0x93, 0x57, + 0xf1, 0x2e, 0x2e, 0xae, 0xad, 0x82, 0x97, 0x7f, 0x04, 0x12, 0xf6, 0x9b, 0xf8, 0xb9, 0x9b, 0xbf, + 0xa1, 0xe5, 0xa8, 0x1b, 0xaa, 0x44, 0x77, 0x55, 0x0b, 0x1d, 0x2d, 0x98, 0x50, 0x2c, 0xe9, 0x21, + 0xad, 0x87, 0x74, 0xf2, 0x7e, 0xb6, 0x38, 0xa5, 0x47, 0x98, 0x16, 0x2c, 0xd6, 0xf7, 0x9f, 0x2b, + 0x26, 0xfa, 0x62, 0x89, 0xf9, 0x44, 0x2d, 0x9e, 0x50, 0x9c, 0xd2, 0xc2, 0xbd, 0xe5, 0xf9, 0x84, + 0x96, 0x92, 0xe8, 0x60, 0x7c, 0x80, 0x66, 0xe8, 0x4f, 0xac, 0xf2, 0x01, 0xa0, 0x5e, 0x0d, 0x54, + 0x92, 0x51, 0x16, 0x84, 0x16, 0xd5, 0x2a, 0xbd, 0xc6, 0x86, 0xac, 0x12, 0x9b, 0x48, 0xad, 0xd2, + 0x3d, 0x4a, 0xdd, 0x87, 0x74, 0x18, 0x8a, 0x40, 0xeb, 0x0b, 0x05, 0x1d, 0x85, 0x1f, 0x86, 0x09, + 0x83, 0xfb, 0x3f, 0xfa, 0xb2, 0x30, 0xf8, 0xd6, 0x42, 0xdf, 0x58, 0xe7, 0x60, 0xc7, 0x33, 0xc4, + 0x1b, 0xcc, 0x6b, 0x0d, 0x95, 0xba, 0x4e, 0x84, 0x91, 0xe6, 0x2f, 0x9f, 0x09, 0x66, 0xff, 0x57, + 0x28, 0x5b, 0x79, 0x40, 0x85, 0x36, 0xb1, 0xe3, 0x75, 0x48, 0x46, 0x26, 0xde, 0xd1, 0x85, 0x7d, + 0xf9, 0xba, 0x32, 0x01, 0xa5, 0x87, 0x1e, 0x25, 0x98, 0xfd, 0xf4, 0x88, 0xe5, 0xb8, 0x54, 0x99, + 0x3f, 0x8d, 0xe8, 0x99, 0x95, 0x6e, 0x26, 0x78, 0xff, 0xe4, 0x18, 0x03, 0x5c, 0x91, 0xf3, 0xff, + 0x8c, 0x9f, 0x7f, 0x54, 0xd0, 0xf5, 0x51, 0xe2, 0xa8, 0x07, 0xd4, 0x61, 0x4e, 0x33, 0x59, 0x48, + 0xfe, 0x35, 0xbc, 0xe3, 0x66, 0x06, 0xe4, 0x6f, 0xff, 0x3a, 0xf8, 0xb5, 0xa7, 0x0b, 0xac, 0xf0, + 0x10, 0xf1, 0x93, 0x41, 0xf9, 0xd8, 0xf6, 0xe7, 0x42, 0x61, 0x0e, 0x84, 0x8b, 0x22, 0x7e, 0xe7, + 0x63, 0x12, 0x69, 0xcc, 0x02, 0x07, 0x87, 0x5c, 0x12, 0xf6, 0xdb, 0xef, 0x37, 0x51, 0x5e, 0x3c, + 0x7a, 0x05, 0x3f, 0xab, 0x98, 0x45, 0x1e, 0x46, 0x77, 0x59, 0x3c, 0x9e, 0x3a, 0xe2, 0x8e, 0x08, + 0xf5, 0x64, 0x63, 0x03, 0x0b, 0xdc, 0x3a, 0x2b, 0xcb, 0xd8, 0xff, 0xa0, 0x4e, 0x13, 0xe3, 0xa1, + 0x7e, 0x9d, 0x0b, 0xa3, 0xb9, 0x1a, 0xad, 0x8d, 0x05, 0x62, 0xbf, 0xca, 0xb8, 0x36, 0x69, 0x98, + 0xa6, 0x6a, 0x66, 0x37, 0xfc, 0x00, 0x6e, 0x7b, 0xe8, 0x5d, 0xc5, 0x57, 0x99, 0x97, 0x21, 0x29, + 0x7a, 0x34, 0xc2, 0x25, 0x00, 0xc6, 0xb1, 0x53, 0x3f, 0x06, 0xcf, 0x2d, 0xbf, 0xe1, 0xee, 0xf7, + 0x96, 0x6d, 0x79, 0xf8, 0x7d, 0x62, 0xd2, 0x24, 0x39, 0x13, 0xf5, 0xd2, 0xaa, 0xc4, 0xd8, 0xde, + 0xbd, 0xeb, 0x9f, 0x6e, 0xc8, 0x93, 0xd6, 0x26, 0x6a, 0x21, 0xd6, 0x85, 0x12, 0xc8, 0xd3, 0xf7, + 0xfe, 0x96, 0xb4, 0xac, 0x6f, 0xf8, 0x7e, 0xcd, 0x94, 0xfe, 0x6d, 0x9a, 0xde, 0xbd, 0x3e, 0x9d, + 0xbc, 0x93, 0x0b, 0xc8, 0xce, 0xf1, 0x81, 0xef, 0x7a, 0xf7, 0xde, 0x81, 0xb6, 0x50, 0x6d, 0x27, + 0x34, 0x0b, 0x81, 0xfb, 0x95, 0x73, 0x6c, 0x6d, 0x76, 0xe0, 0x07, 0x59, 0x01, 0xee, 0xa8, 0x07, + 0xb7, 0x05, 0xa1, 0xc6, 0xe9, 0x91, 0xff, 0xee, 0x18, 0x71, 0x1d, 0xd0, 0x0c, 0x03, 0x42, 0x23, + 0xf8, 0xda, 0x6b, 0xa1, 0x34, 0xab, 0x30, 0xa3, 0xd2, 0x61, 0x0a, 0x7e, 0x50, 0x73, 0x38, 0x1d, + 0xae, 0xb4, 0x8f, 0x4a, 0x6b, 0x94, 0x96, 0x51, 0xe9, 0x08, 0xc5, 0x33, 0x2a, 0x1d, 0xa9, 0xec, + 0x1f, 0x95, 0x1e, 0xa3, 0xbc, 0xab, 0xa6, 0xd7, 0xd1, 0xa4, 0x56, 0xf9, 0x09, 0x4d, 0xde, 0x2d, + 0x8f, 0x52, 0x5c, 0x23, 0xcb, 0xa3, 0x95, 0xe7, 0x83, 0xe5, 0x6a, 0x7a, 0xac, 0x52, 0x30, 0x2a, + 0xad, 0x53, 0x72, 0x46, 0xa5, 0xc7, 0x29, 0x69, 0xa3, 0xd2, 0xe3, 0x15, 0xe3, 0x68, 0xf8, 0x9c, + 0x62, 0x18, 0x85, 0x8f, 0x5e, 0xd1, 0x8f, 0xec, 0x2f, 0x46, 0x61, 0x47, 0xd7, 0x9f, 0xa0, 0xe0, + 0x9e, 0xf3, 0x70, 0x7a, 0xa2, 0xd2, 0x3e, 0x2a, 0x1d, 0xab, 0xb4, 0x8c, 0x4a, 0xdf, 0xa3, 0x78, + 0x46, 0xa5, 0x27, 0x29, 0xfb, 0x47, 0xa5, 0xef, 0x55, 0xde, 0x1d, 0x95, 0x8e, 0x53, 0x5e, 0x1b, + 0x95, 0x8e, 0x57, 0x5c, 0xa3, 0xd2, 0x93, 0xe9, 0xa1, 0xcc, 0xe1, 0xf4, 0x14, 0xe5, 0x99, 0x51, + 0xe9, 0x04, 0xc5, 0x3c, 0x2a, 0x3d, 0x55, 0x49, 0xfd, 0x6e, 0xc4, 0x78, 0xa6, 0x29, 0xc6, 0xef, + 0x46, 0x8d, 0x67, 0xba, 0x62, 0xf8, 0x4e, 0x3d, 0x03, 0xc3, 0xa0, 0x33, 0x81, 0x5f, 0x02, 0xc0, + 0x93, 0xfa, 0x18, 0xd1, 0xa1, 0xf0, 0x32, 0x78, 0x02, 0x2f, 0x19, 0x37, 0xab, 0xe0, 0xc9, 0xc8, + 0x4c, 0x4e, 0x36, 0x32, 0x69, 0x4e, 0x67, 0xd1, 0xe6, 0x72, 0x67, 0x51, 0xa1, 0x61, 0x6b, 0xd9, + 0x26, 0x61, 0x73, 0xd1, 0xfa, 0x8a, 0xa2, 0x82, 0xc2, 0xd9, 0x49, 0x86, 0xb2, 0x2d, 0x86, 0xf2, + 0xed, 0x45, 0xcc, 0x6a, 0xd3, 0x0a, 0xc6, 0x52, 0xb4, 0x41, 0xa8, 0x28, 0x71, 0xee, 0x60, 0xd6, + 0x6c, 0x2d, 0xaa, 0x28, 0xde, 0x54, 0xb6, 0x8d, 0xd9, 0x5c, 0xb4, 0x45, 0x60, 0x4c, 0x45, 0x9b, + 0xcb, 0x2a, 0x76, 0x18, 0x36, 0x17, 0x94, 0x1b, 0x8a, 0xb6, 0xdb, 0x0b, 0x04, 0x07, 0x00, 0x99, + 0xcb, 0x98, 0xd7, 0xf1, 0xab, 0x6d, 0x0f, 0x32, 0xb3, 0x1c, 0x90, 0xb9, 0xa1, 0xa8, 0xdc, 0x59, + 0x02, 0x80, 0x0a, 0x9c, 0x86, 0x59, 0xdb, 0xe7, 0x1a, 0xf8, 0x8a, 0x8a, 0xb2, 0x0a, 0xc3, 0x86, + 0xb2, 0xc2, 0xa2, 0xc5, 0x90, 0x06, 0xb0, 0x1b, 0x01, 0x8e, 0xd3, 0xb0, 0xa5, 0xcc, 0x69, 0x28, + 0xaf, 0x28, 0x72, 0xc0, 0x3b, 0x03, 0x5d, 0x1a, 0xa0, 0x13, 0x07, 0xb6, 0x72, 0x96, 0x95, 0x19, + 0xca, 0x36, 0x15, 0x32, 0x45, 0xdb, 0x9d, 0x58, 0xad, 0x18, 0xda, 0x3e, 0xbb, 0xa9, 0x6c, 0xc3, + 0x73, 0xb4, 0x41, 0x71, 0x99, 0xb0, 0xa5, 0x90, 0x59, 0xb1, 0x65, 0x6b, 0xc1, 0xa6, 0x92, 0x42, + 0x43, 0x59, 0x39, 0x42, 0x65, 0xd6, 0x42, 0x8b, 0xcd, 0x05, 0x5b, 0x76, 0x18, 0xf8, 0x45, 0x0f, + 0x25, 0x1b, 0xa0, 0x51, 0x45, 0x49, 0x91, 0x63, 0x06, 0x93, 0x51, 0x26, 0x6c, 0x2a, 0xa4, 0xad, + 0x8a, 0xb6, 0x14, 0x3c, 0xbb, 0xa9, 0xc8, 0x90, 0x06, 0xa5, 0x9b, 0x4a, 0xb6, 0x14, 0x21, 0xe8, + 0x87, 0x16, 0x1b, 0xcc, 0x05, 0x15, 0x4e, 0x43, 0x59, 0xb1, 0xa1, 0xbc, 0xc0, 0x69, 0x37, 0x94, + 0x38, 0x68, 0xcd, 0xc2, 0x92, 0x8a, 0xa2, 0x0d, 0x4e, 0x1c, 0xdf, 0x16, 0xe8, 0xd7, 0xb1, 0x63, + 0x33, 0xd4, 0x7f, 0x2e, 0x9a, 0xb1, 0xac, 0x30, 0x65, 0x32, 0x4c, 0x3a, 0xd0, 0xe8, 0xb9, 0xf2, + 0xb2, 0x12, 0x40, 0x38, 0xbb, 0x68, 0x4b, 0x51, 0x45, 0xc1, 0x26, 0x18, 0x40, 0x99, 0x13, 0x1a, + 0x20, 0xde, 0xc5, 0x05, 0xc2, 0x26, 0x27, 0x93, 0x59, 0xe2, 0x78, 0xce, 0x50, 0x44, 0x47, 0x8c, + 0x63, 0xcf, 0xac, 0x28, 0xd9, 0x5a, 0x84, 0xa3, 0x56, 0xbb, 0xcc, 0x4b, 0xcb, 0x5d, 0xbd, 0x62, + 0x75, 0xf6, 0x62, 0x43, 0x56, 0x09, 0xe0, 0xe3, 0xd8, 0x01, 0xb4, 0xdb, 0x6c, 0xb0, 0x17, 0x00, + 0xd1, 0xb6, 0x6c, 0xa8, 0xd8, 0xa1, 0x52, 0xad, 0xb8, 0xa8, 0xc0, 0x29, 0x54, 0x14, 0x01, 0x27, + 0xe6, 0x18, 0x1c, 0x4e, 0xa1, 0xb8, 0x18, 0xc6, 0x06, 0xe4, 0x2e, 0x71, 0x3c, 0x5b, 0x64, 0x2f, + 0xd8, 0x5a, 0x14, 0xcd, 0xac, 0xe7, 0x33, 0x96, 0xaf, 0xcf, 0xb2, 0xac, 0x67, 0xf8, 0xac, 0x15, + 0x06, 0x73, 0x5a, 0xee, 0x5a, 0x24, 0xbe, 0xa1, 0x64, 0x8b, 0xc3, 0x59, 0xb0, 0x69, 0x53, 0x01, + 0x85, 0xb1, 0xc1, 0x5e, 0x04, 0x04, 0x2b, 0x2e, 0x80, 0x5e, 0x0a, 0x91, 0xb8, 0x8b, 0x0d, 0x16, + 0x61, 0xc3, 0x86, 0x22, 0x87, 0xa3, 0x58, 0xd8, 0xb4, 0x69, 0x07, 0xd4, 0x2d, 0x71, 0x96, 0x00, + 0x05, 0x5f, 0x28, 0x2a, 0x8c, 0x66, 0x9c, 0xc5, 0xce, 0x72, 0x28, 0x2f, 0xaa, 0x00, 0x06, 0x20, + 0x19, 0x80, 0x21, 0x85, 0x25, 0x5b, 0x36, 0x1a, 0x9c, 0xf6, 0x22, 0x43, 0x31, 0xa2, 0x59, 0xb2, + 0xc5, 0xe0, 0xd8, 0x0c, 0xa0, 0xa1, 0xb8, 0xbc, 0x60, 0xc3, 0x73, 0x45, 0x4e, 0x87, 0x61, 0x76, + 0x89, 0x13, 0xeb, 0x01, 0x7f, 0x0b, 0x0d, 0xcf, 0xee, 0x70, 0x16, 0x39, 0x92, 0xe6, 0x18, 0x0a, + 0xcb, 0xb6, 0x6d, 0xd9, 0x54, 0x56, 0x50, 0x08, 0xa8, 0x6e, 0xb4, 0x3b, 0x0d, 0xce, 0x82, 0xe7, + 0x8a, 0x0c, 0x9b, 0xca, 0xb6, 0x6c, 0x2c, 0xaa, 0x98, 0x1b, 0xcd, 0x64, 0xa5, 0xad, 0x9d, 0xff, + 0x10, 0x93, 0x45, 0x11, 0x02, 0x0e, 0x1b, 0x68, 0x45, 0x40, 0x78, 0x63, 0x91, 0x61, 0xfe, 0x5c, + 0x66, 0xde, 0xb3, 0x65, 0x65, 0xce, 0x79, 0x9b, 0x4a, 0x36, 0x03, 0x73, 0x7e, 0xf8, 0x6c, 0x49, + 0x99, 0x63, 0x2e, 0x90, 0x86, 0xf9, 0x5e, 0xda, 0xe0, 0x00, 0x7c, 0x01, 0x99, 0x0d, 0x65, 0x15, + 0xc8, 0x23, 0x00, 0x3a, 0xe5, 0xc9, 0xf9, 0xc6, 0xcd, 0xe6, 0xb4, 0xd5, 0x2b, 0x32, 0xe0, 0xed, + 0x91, 0x25, 0xc6, 0xcd, 0x53, 0x9e, 0x4c, 0xde, 0xbc, 0xd8, 0xc0, 0xa4, 0x01, 0xf3, 0xb6, 0xfc, + 0x50, 0x70, 0x50, 0xa6, 0x6f, 0x1e, 0x21, 0xae, 0x20, 0x19, 0x3b, 0x70, 0x88, 0x40, 0xab, 0x92, + 0xc2, 0x22, 0x43, 0x81, 0x21, 0x58, 0xc7, 0xa1, 0xb2, 0x70, 0x2e, 0x73, 0x97, 0x3f, 0x6b, 0xd7, + 0xac, 0x31, 0x98, 0xd2, 0x56, 0xff, 0xc8, 0x60, 0x5b, 0xb3, 0xca, 0x6a, 0xe2, 0x2d, 0x23, 0xa5, + 0xa9, 0xb0, 0xc8, 0x59, 0x54, 0x81, 0xa8, 0x19, 0x10, 0x6d, 0x43, 0x21, 0xb2, 0x98, 0xa1, 0x68, + 0x40, 0xdf, 0xc9, 0x21, 0x56, 0x0b, 0x5b, 0x00, 0xcb, 0x32, 0xa0, 0x29, 0xed, 0x81, 0x4a, 0x84, + 0x43, 0x15, 0xdf, 0x68, 0xc6, 0x0c, 0x62, 0xef, 0x80, 0xee, 0x9f, 0x2b, 0xda, 0x81, 0xc4, 0xa8, + 0x28, 0x02, 0x86, 0xa3, 0xe0, 0x1b, 0x66, 0x39, 0xe6, 0x06, 0xf9, 0x91, 0xb1, 0xa9, 0xcc, 0x51, + 0x44, 0x39, 0x08, 0xb2, 0x00, 0x52, 0xb5, 0xb5, 0x04, 0x95, 0x83, 0x51, 0x35, 0x41, 0x25, 0x2b, + 0x70, 0xa8, 0x60, 0x8b, 0x41, 0x55, 0x13, 0xe8, 0x37, 0x99, 0xb1, 0x38, 0x81, 0x3d, 0xce, 0x8a, + 0x82, 0x0d, 0x45, 0x8b, 0xa3, 0x19, 0x83, 0xe1, 0xc9, 0x59, 0xe5, 0xf9, 0xd1, 0xcc, 0x72, 0xe0, + 0x46, 0x88, 0x08, 0xc0, 0xc4, 0xb2, 0x0d, 0x05, 0x20, 0xde, 0x8b, 0x0d, 0x6b, 0x04, 0x2a, 0xfb, + 0x6a, 0x81, 0xaa, 0xbd, 0xc0, 0x8f, 0x0a, 0x61, 0x03, 0x95, 0x3d, 0x47, 0xc9, 0xc6, 0x2d, 0xaa, + 0x14, 0x22, 0xb5, 0x05, 0xb4, 0x13, 0x4c, 0x3a, 0xe2, 0x6e, 0xa8, 0x28, 0x80, 0xae, 0xa9, 0x8e, + 0x17, 0x15, 0x42, 0xa6, 0x19, 0x39, 0xa8, 0x4a, 0x7e, 0x49, 0x50, 0x29, 0x83, 0x7a, 0xbb, 0xb9, + 0x60, 0x63, 0xc9, 0x86, 0x20, 0x2d, 0xf8, 0x2d, 0x4e, 0xb0, 0x23, 0x21, 0x1d, 0xab, 0x28, 0xda, + 0x28, 0x6c, 0x2a, 0xa8, 0x50, 0x85, 0x6b, 0x94, 0x9a, 0x3d, 0xf6, 0xd8, 0x63, 0x4c, 0x51, 0x61, + 0x09, 0x20, 0x88, 0x02, 0xc3, 0xcc, 0x9d, 0xc7, 0x44, 0x33, 0xab, 0xd7, 0x66, 0x59, 0x82, 0x60, + 0xb0, 0xc1, 0x08, 0x9d, 0x11, 0xb6, 0x38, 0x84, 0xf2, 0xf2, 0xb2, 0x0a, 0x34, 0x62, 0x41, 0xa5, + 0x71, 0x80, 0xaa, 0x45, 0x87, 0x2c, 0xc7, 0xb0, 0xbd, 0x30, 0x8d, 0x1a, 0xbe, 0xaa, 0xac, 0x94, + 0xb0, 0x73, 0x99, 0x19, 0x30, 0x74, 0x26, 0xb3, 0x68, 0x6b, 0xc9, 0x86, 0x22, 0xda, 0xa0, 0x60, + 0x2b, 0x94, 0x20, 0xcb, 0xee, 0x1a, 0x99, 0xb5, 0x16, 0x0b, 0x13, 0x3d, 0x63, 0x86, 0xc1, 0xa2, + 0x4a, 0x6b, 0x08, 0xed, 0x20, 0xec, 0x19, 0x58, 0xb4, 0x1c, 0xf4, 0xd2, 0xb0, 0xa3, 0x4c, 0x00, + 0x6a, 0x95, 0x97, 0x00, 0x36, 0xdf, 0x97, 0x5c, 0xe0, 0x2c, 0x6a, 0x53, 0x05, 0x88, 0xcb, 0x1c, + 0x03, 0x15, 0x76, 0xf8, 0x51, 0x2b, 0xcd, 0x31, 0x00, 0x01, 0x46, 0xca, 0x3f, 0xc2, 0x0b, 0x59, + 0x21, 0x30, 0x63, 0xc8, 0xa4, 0x32, 0x10, 0x35, 0xf8, 0x41, 0x10, 0xe5, 0x60, 0xb3, 0x4a, 0x70, + 0x04, 0x0e, 0xb4, 0xd4, 0x98, 0xa3, 0xca, 0x20, 0x1d, 0xc0, 0x63, 0xd1, 0xd1, 0xcc, 0x3f, 0x68, + 0x91, 0x2a, 0x6b, 0x19, 0x6b, 0x73, 0x57, 0x3d, 0x98, 0xb6, 0x6a, 0xed, 0x83, 0x99, 0xfc, 0x2a, + 0x55, 0xe4, 0xb0, 0xdd, 0x5c, 0x55, 0x64, 0x7e, 0xe8, 0x08, 0x9a, 0x64, 0x95, 0x91, 0x69, 0x9b, + 0x80, 0xfb, 0x34, 0x4d, 0xcd, 0x08, 0x63, 0x2a, 0xd8, 0x60, 0x47, 0x69, 0x57, 0x53, 0xc1, 0x0e, + 0xfe, 0xa1, 0x9f, 0xb9, 0xc0, 0xad, 0x7f, 0xa0, 0xb3, 0x03, 0x86, 0xe2, 0xc0, 0xe4, 0x36, 0x90, + 0x15, 0x55, 0xb0, 0x87, 0x6d, 0x40, 0x59, 0x79, 0xd1, 0x16, 0x95, 0x9a, 0xb3, 0xb6, 0x23, 0x15, + 0x9e, 0x05, 0x93, 0xa0, 0x1a, 0x18, 0xaa, 0xea, 0xa3, 0xac, 0xc2, 0xff, 0xd3, 0x38, 0x3c, 0x2b, + 0x94, 0x80, 0x7a, 0xae, 0xc8, 0x44, 0x43, 0xb9, 0xb9, 0xc0, 0xb9, 0xc1, 0x3e, 0x37, 0xfa, 0xae, + 0x99, 0x07, 0xf3, 0x5e, 0x58, 0x56, 0xa4, 0x0a, 0x1f, 0xd8, 0x1c, 0xb0, 0xfa, 0x60, 0xd2, 0xe6, + 0x05, 0x8b, 0x2d, 0xaa, 0xf0, 0x39, 0x0c, 0xdb, 0x4a, 0xb0, 0x5e, 0x91, 0xc3, 0x59, 0xb2, 0x45, + 0x95, 0x11, 0x9c, 0x17, 0x1c, 0xa3, 0x74, 0x6d, 0x61, 0x32, 0x10, 0xa1, 0xa0, 0x62, 0x94, 0xe8, + 0x45, 0x33, 0x3c, 0xa8, 0x05, 0xb2, 0x07, 0x15, 0x6f, 0xae, 0x01, 0x0c, 0xc5, 0x96, 0xad, 0x40, + 0x3c, 0x80, 0x00, 0xf3, 0xc3, 0xe6, 0x7f, 0x2a, 0x79, 0x40, 0x8c, 0xcc, 0x32, 0x01, 0xed, 0x82, + 0x4a, 0xf1, 0xed, 0x8b, 0x1e, 0x61, 0x6c, 0x25, 0x15, 0x4e, 0x01, 0x04, 0xce, 0x41, 0xab, 0x31, + 0x25, 0x8e, 0xb2, 0x94, 0x85, 0x0b, 0x93, 0xd5, 0x99, 0x62, 0x4b, 0xc1, 0xe6, 0x22, 0xd5, 0xfc, + 0xdd, 0x55, 0xbc, 0x64, 0xe3, 0x43, 0xf3, 0x17, 0x3c, 0xbc, 0xf0, 0x91, 0x45, 0x29, 0x05, 0xcf, + 0x6e, 0x28, 0x2c, 0x2a, 0x0e, 0xea, 0xbb, 0x61, 0xe9, 0x2c, 0xc7, 0x83, 0xb3, 0xca, 0x1f, 0x8d, + 0x66, 0x56, 0x58, 0xd6, 0xa8, 0x00, 0xb6, 0x94, 0xc1, 0x2c, 0x55, 0xb2, 0xb9, 0x00, 0xd0, 0x50, + 0xa7, 0x7a, 0x1c, 0xe4, 0x86, 0x8a, 0x92, 0x72, 0x54, 0xb3, 0x19, 0x38, 0xf3, 0xfe, 0x33, 0x6d, + 0x57, 0x99, 0x95, 0x0b, 0x4e, 0xc1, 0xb0, 0x11, 0x2a, 0x7a, 0x56, 0xd8, 0xc8, 0xac, 0xcb, 0xe2, + 0x73, 0x99, 0xd9, 0x5b, 0x60, 0x1e, 0x49, 0x0a, 0x56, 0x0a, 0x29, 0xca, 0x0a, 0xf3, 0xd6, 0x05, + 0x86, 0x82, 0xc2, 0x42, 0x14, 0xb8, 0xc5, 0x86, 0x99, 0xb3, 0x1c, 0x33, 0xd1, 0x19, 0xd1, 0x80, + 0x23, 0xa2, 0x67, 0xc3, 0x34, 0x5a, 0xbd, 0x21, 0xd5, 0x45, 0x9d, 0x13, 0x70, 0x4a, 0xe6, 0xc2, + 0x7f, 0xf8, 0xcc, 0x63, 0xa8, 0xdc, 0x30, 0xf1, 0xc9, 0x2c, 0xe3, 0x30, 0xaa, 0xcf, 0xab, 0xc1, + 0xdf, 0x06, 0xe3, 0x70, 0x1e, 0x96, 0x6b, 0xcd, 0x2c, 0x23, 0x43, 0x70, 0xb5, 0x03, 0x3c, 0xf6, + 0x3d, 0xe0, 0xe5, 0xbf, 0x0c, 0xbf, 0xaf, 0x42, 0xde, 0xbd, 0xf0, 0xbe, 0x31, 0x87, 0x65, 0xae, + 0x58, 0x58, 0xe6, 0x5b, 0x48, 0xef, 0x84, 0xf7, 0x0b, 0x50, 0x56, 0x00, 0x91, 0xee, 0xcf, 0xa0, + 0xec, 0x3d, 0xb3, 0x9a, 0xff, 0x15, 0x94, 0x0b, 0x90, 0xe7, 0xce, 0xc5, 0xfd, 0x7e, 0x08, 0xcc, + 0x82, 0xf5, 0xff, 0x5f, 0x4f, 0x25, 0xc0, 0x4a, 0x5e, 0xc9, 0x32, 0xa9, 0xf0, 0x98, 0xe1, 0x79, + 0x06, 0x9e, 0x72, 0x78, 0x5c, 0xf0, 0xbc, 0x06, 0xcf, 0xbb, 0xf0, 0xec, 0x87, 0xc7, 0x03, 0x4f, + 0x0b, 0x3c, 0xed, 0xf0, 0xf8, 0xf1, 0x14, 0xd2, 0xe3, 0x2c, 0xa3, 0x87, 0xc7, 0x00, 0x4f, 0x32, + 0x3c, 0xa9, 0xf0, 0x98, 0xe1, 0x79, 0x06, 0x9e, 0x72, 0x78, 0x5c, 0xf0, 0xbc, 0x06, 0xcf, 0xbb, + 0xf0, 0xec, 0x87, 0xc7, 0x03, 0x4f, 0x0b, 0x3c, 0xed, 0xf0, 0xf8, 0xe1, 0x61, 0xa0, 0x5f, 0x3d, + 0x3c, 0x06, 0x78, 0xd0, 0x9f, 0x8b, 0xc5, 0xb5, 0x57, 0x3c, 0x0a, 0xb9, 0xda, 0xca, 0xe4, 0xbf, + 0x37, 0x79, 0xab, 0xa3, 0xc9, 0xf5, 0xb3, 0xb5, 0xaf, 0x14, 0x64, 0xaf, 0x4e, 0x88, 0xaf, 0x5e, + 0xb2, 0xf4, 0x50, 0x52, 0x2a, 0x84, 0x22, 0x8e, 0xf2, 0x92, 0x2d, 0x42, 0x39, 0x33, 0xf9, 0x26, + 0xc3, 0xac, 0x5f, 0xbf, 0xb9, 0xac, 0xb0, 0xb0, 0x64, 0x3e, 0x43, 0x68, 0x42, 0x28, 0x2c, 0xd9, + 0x8a, 0xa9, 0xbd, 0x7f, 0x0f, 0xa5, 0x68, 0xf1, 0x02, 0x46, 0x33, 0x40, 0x33, 0x82, 0x95, 0xc7, + 0xde, 0x62, 0x18, 0x50, 0xd9, 0xe7, 0xa8, 0x3b, 0xb8, 0xde, 0x41, 0xad, 0x90, 0x83, 0xf1, 0x87, + 0x72, 0x37, 0x40, 0xb6, 0xb3, 0x68, 0x7d, 0xc9, 0x96, 0xc2, 0xa2, 0xed, 0x4c, 0x09, 0xb8, 0x9b, + 0x74, 0x4a, 0x65, 0xac, 0x2c, 0xb0, 0x09, 0xcd, 0xe3, 0xfc, 0xf5, 0xe8, 0x5a, 0x30, 0x2b, 0xc3, + 0x58, 0xaa, 0x5d, 0xeb, 0x51, 0xc5, 0x99, 0xb5, 0x9a, 0x60, 0x6a, 0x63, 0x91, 0x13, 0xca, 0xd1, + 0x63, 0x0b, 0x8b, 0x0c, 0x66, 0x81, 0x3d, 0x73, 0x14, 0xad, 0x47, 0x7b, 0x07, 0x73, 0x98, 0x5b, + 0x0b, 0x60, 0x54, 0x75, 0x5c, 0xef, 0x2c, 0x0b, 0x56, 0xcd, 0x8c, 0x62, 0x99, 0x60, 0xb7, 0x54, + 0x8b, 0xd6, 0xc3, 0x4c, 0xce, 0xe0, 0xa7, 0x31, 0x69, 0x7b, 0x44, 0x93, 0x79, 0x2e, 0x94, 0xda, + 0x80, 0x93, 0x26, 0xf3, 0xfe, 0xd8, 0x11, 0xfd, 0x6d, 0x14, 0x4a, 0x0a, 0x99, 0x09, 0xba, 0x11, + 0x39, 0x60, 0xdd, 0x8b, 0x36, 0x31, 0x2f, 0x43, 0x16, 0xed, 0x40, 0x05, 0x71, 0x73, 0x3c, 0x04, + 0x7d, 0x05, 0xce, 0xf9, 0x23, 0xab, 0xdc, 0xc3, 0x85, 0xf2, 0x70, 0x50, 0xeb, 0x37, 0x94, 0x6d, + 0x71, 0x02, 0x10, 0x26, 0x21, 0x26, 0x94, 0x4d, 0x47, 0x77, 0x71, 0xc2, 0xc8, 0x24, 0x54, 0x65, + 0x76, 0x4e, 0x02, 0x8c, 0xc1, 0x66, 0x16, 0x01, 0x3e, 0xe8, 0x1d, 0x57, 0xac, 0x07, 0xa3, 0x01, + 0xf9, 0xf8, 0x95, 0x14, 0xb5, 0x26, 0xed, 0x72, 0xcd, 0xdd, 0xa4, 0x8a, 0xf6, 0x0e, 0x48, 0x53, + 0xaa, 0x8f, 0x6e, 0xb5, 0x23, 0xee, 0x7b, 0xd9, 0xc5, 0x15, 0x65, 0x9b, 0x29, 0x11, 0x1e, 0x88, + 0x07, 0x00, 0x8e, 0x11, 0x08, 0xa7, 0x0d, 0x67, 0xd0, 0x61, 0xaf, 0xc4, 0x34, 0x45, 0xb2, 0x0d, + 0xdf, 0xd4, 0x6e, 0xa6, 0x4e, 0x86, 0x57, 0x8a, 0x40, 0x46, 0xe8, 0x0d, 0xe8, 0xca, 0x3c, 0x31, + 0x22, 0x81, 0x92, 0x53, 0xc4, 0xdc, 0x98, 0xc2, 0x86, 0xac, 0x90, 0x3a, 0x52, 0xbc, 0x80, 0x19, + 0xca, 0xa0, 0x00, 0xca, 0x47, 0x64, 0xa8, 0xc0, 0xdd, 0x34, 0x07, 0xcc, 0x0d, 0x70, 0xf3, 0xa7, + 0xf0, 0xee, 0x2c, 0x03, 0x33, 0x59, 0x54, 0xc1, 0xfc, 0x16, 0xde, 0x0b, 0x9e, 0x75, 0x30, 0x87, + 0xa6, 0xa3, 0xa0, 0x54, 0x6c, 0x28, 0xdf, 0xc1, 0x5c, 0x0b, 0xbe, 0x6e, 0x2e, 0x67, 0xf0, 0x43, + 0x20, 0xf8, 0x5a, 0x00, 0xf2, 0x06, 0xc9, 0x3d, 0x6a, 0x72, 0x0b, 0xbe, 0x9f, 0x51, 0xdf, 0xc1, + 0x04, 0x32, 0x5f, 0x18, 0x90, 0x63, 0x30, 0x36, 0x30, 0x5c, 0x20, 0x54, 0x33, 0x58, 0x06, 0x0c, + 0x9f, 0x2a, 0x27, 0x4e, 0x66, 0x0b, 0x24, 0x0b, 0x4b, 0x36, 0x02, 0x9b, 0x82, 0x19, 0xbf, 0x9a, + 0x41, 0x1b, 0x02, 0x02, 0x25, 0xcc, 0x03, 0x33, 0xc1, 0x42, 0x40, 0x43, 0xc0, 0x00, 0x0c, 0x20, + 0x08, 0x12, 0x5a, 0x76, 0xe6, 0xc5, 0xfb, 0x40, 0x0f, 0x0b, 0xb6, 0x80, 0x93, 0xb2, 0x3c, 0x91, + 0x65, 0x46, 0x44, 0x41, 0xcc, 0x9c, 0xfb, 0xa1, 0x7e, 0xb9, 0x73, 0x98, 0x90, 0xc7, 0xee, 0xc7, + 0x61, 0xad, 0xa7, 0x66, 0x6e, 0xfd, 0xe6, 0x67, 0x2b, 0x18, 0xe7, 0x6c, 0x96, 0x81, 0x5f, 0x55, + 0xa2, 0x0b, 0x99, 0x7d, 0xb3, 0x11, 0x54, 0x05, 0x6d, 0xc1, 0x2c, 0x9e, 0x7b, 0x17, 0x1a, 0x16, + 0x3f, 0xbb, 0x43, 0x85, 0xf1, 0xbb, 0x7f, 0xc8, 0x2e, 0x76, 0xa8, 0x6c, 0xbb, 0xfd, 0x0f, 0x25, + 0x1b, 0xca, 0xca, 0x2a, 0x0a, 0x99, 0x25, 0xf3, 0xbe, 0x9f, 0x8f, 0xb3, 0xdd, 0x7a, 0xd5, 0xdf, + 0x2c, 0x86, 0x42, 0x95, 0xce, 0x2f, 0x61, 0x35, 0xf5, 0xf5, 0xa3, 0xf9, 0x98, 0x09, 0x42, 0xc8, + 0x54, 0x2f, 0x50, 0xdf, 0x60, 0xf4, 0xf3, 0x1e, 0x56, 0x5f, 0xb7, 0x33, 0x0f, 0x2e, 0x0c, 0xb6, + 0x59, 0xef, 0xb8, 0xeb, 0x29, 0x32, 0x7f, 0x81, 0x4c, 0x10, 0xed, 0xad, 0xeb, 0x61, 0xaa, 0x52, + 0x35, 0x8c, 0x39, 0xfc, 0x08, 0x8c, 0xae, 0x68, 0x33, 0xc8, 0x58, 0x50, 0xe5, 0xa8, 0xd3, 0xc7, + 0x0c, 0x40, 0xb6, 0xa3, 0x00, 0x43, 0x07, 0x50, 0xd9, 0x60, 0x94, 0xc5, 0x78, 0x96, 0xa8, 0xb4, + 0x55, 0xeb, 0x33, 0xdd, 0x4b, 0x90, 0x49, 0x25, 0x77, 0xd3, 0x63, 0x1f, 0x55, 0x8b, 0x2b, 0x0a, + 0xb6, 0x85, 0xb2, 0x0c, 0x90, 0x55, 0xbe, 0x79, 0x33, 0xc8, 0x71, 0x51, 0x11, 0x53, 0xf2, 0x28, + 0xd5, 0xcc, 0x11, 0x9d, 0xef, 0xfe, 0x7e, 0xce, 0x7a, 0xe7, 0x8e, 0x72, 0xd4, 0x7d, 0x98, 0xa4, + 0x60, 0x5e, 0xfa, 0xf9, 0xff, 0x59, 0xac, 0x4a, 0x6e, 0xe3, 0x63, 0x80, 0x3f, 0x62, 0xaf, 0x1a, + 0x9c, 0xe2, 0x32, 0x66, 0x63, 0xea, 0x3f, 0x1b, 0x11, 0x2a, 0xab, 0x94, 0xa6, 0x62, 0xb3, 0xa5, + 0x68, 0xdb, 0x7a, 0xd5, 0x98, 0x6d, 0xcf, 0x60, 0x31, 0x64, 0x02, 0x62, 0x6f, 0x29, 0x5c, 0xaf, + 0xd2, 0x9f, 0x91, 0x82, 0x79, 0xd4, 0xba, 0xd9, 0x32, 0x59, 0x3a, 0xf3, 0xa9, 0x5a, 0xf1, 0xdf, + 0xd9, 0x20, 0xda, 0x0f, 0x81, 0x02, 0x50, 0xef, 0x28, 0x66, 0xb9, 0x9a, 0x52, 0x23, 0x4e, 0xe6, + 0xe8, 0xf2, 0x20, 0x39, 0x8a, 0x20, 0x32, 0x65, 0x56, 0xaf, 0x40, 0xdc, 0x31, 0x3a, 0x66, 0x36, + 0xaf, 0x08, 0x16, 0x94, 0x14, 0x3a, 0x71, 0x69, 0x26, 0xa0, 0xfe, 0xbf, 0x7d, 0xd8, 0xd0, 0xff, + 0xe4, 0x47, 0xff, 0xbd, 0xff, 0xe7, 0x0f, 0x96, 0xff, 0x7b, 0xf0, 0xf7, 0x8d, 0x50, 0xfa, 0x6c, + 0x30, 0x7d, 0x56, 0xad, 0xf4, 0xef, 0x06, 0xf5, 0xf7, 0x8d, 0xe1, 0xff, 0x8b, 0xd4, 0xff, 0x07, + 0x6e, 0xe1, 0x51, 0x7d, 0x40, 0x6c, 0x00, 0x00, +}; diff --git a/FloridOS/limine/limine-bios-pxe.bin b/FloridOS/limine/limine-bios-pxe.bin new file mode 100644 index 0000000..9f7968b Binary files /dev/null and b/FloridOS/limine/limine-bios-pxe.bin differ diff --git a/FloridOS/limine/limine-bios.sys b/FloridOS/limine/limine-bios.sys new file mode 100644 index 0000000..067c730 Binary files /dev/null and b/FloridOS/limine/limine-bios.sys differ diff --git a/FloridOS/limine/limine-uefi-cd.bin b/FloridOS/limine/limine-uefi-cd.bin new file mode 100644 index 0000000..af0f804 Binary files /dev/null and b/FloridOS/limine/limine-uefi-cd.bin differ diff --git a/FloridOS/limine/limine.c b/FloridOS/limine/limine.c new file mode 100644 index 0000000..5b4b63b --- /dev/null +++ b/FloridOS/limine/limine.c @@ -0,0 +1,1290 @@ +#undef IS_WINDOWS +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) +#define IS_WINDOWS 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef LIMINE_NO_BIOS +#include "limine-bios-hdd.h" +#endif + +static char *program_name = NULL; + +static void perror_wrap(const char *fmt, ...) { + int old_errno = errno; + + fprintf(stderr, "%s: ", program_name); + + va_list args; + va_start(args, fmt); + + vfprintf(stderr, fmt, args); + + va_end(args); + + fprintf(stderr, ": %s\n", strerror(old_errno)); +} + +static void remove_arg(int *argc, char *argv[], int index) { + for (int i = index; i < *argc - 1; i++) { + argv[i] = argv[i + 1]; + } + + (*argc)--; + + argv[*argc] = NULL; +} + +#ifndef LIMINE_NO_BIOS + +static bool quiet = false; + +static int set_pos(FILE *stream, uint64_t pos) { + if (sizeof(long) >= 8) { + return fseek(stream, (long)pos, SEEK_SET); + } + + long jump_size = (LONG_MAX / 2) + 1; + long last_jump = pos % jump_size; + uint64_t jumps = pos / jump_size; + + rewind(stream); + + for (uint64_t i = 0; i < jumps; i++) { + if (fseek(stream, jump_size, SEEK_CUR) != 0) { + return -1; + } + } + if (fseek(stream, last_jump, SEEK_CUR) != 0) { + return -1; + } + + return 0; +} + +#define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b)) + +struct gpt_table_header { + // the head + char signature[8]; + uint32_t revision; + uint32_t header_size; + uint32_t crc32; + uint32_t _reserved0; + + // the partitioning info + uint64_t my_lba; + uint64_t alternate_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + + // the guid + uint64_t disk_guid[2]; + + // entries related + uint64_t partition_entry_lba; + uint32_t number_of_partition_entries; + uint32_t size_of_partition_entry; + uint32_t partition_entry_array_crc32; +}; + +struct gpt_entry { + uint64_t partition_type_guid[2]; + + uint64_t unique_partition_guid[2]; + + uint64_t starting_lba; + uint64_t ending_lba; + + uint64_t attributes; + + uint16_t partition_name[36]; +}; + +// This table from https://web.mit.edu/freebsd/head/sys/libkern/crc32.c +static const uint32_t crc32_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +static uint32_t crc32(void *_stream, size_t len) { + uint8_t *stream = _stream; + uint32_t ret = 0xffffffff; + + for (size_t i = 0; i < len; i++) { + ret = (ret >> 8) ^ crc32_table[(ret ^ stream[i]) & 0xff]; + } + + ret ^= 0xffffffff; + return ret; +} + +static uint16_t endswap16(uint16_t value) { + uint16_t ret = 0; + ret |= (value >> 8) & 0x00ff; + ret |= (value << 8) & 0xff00; + return ret; +} + +static uint32_t endswap32(uint32_t value) { + uint32_t ret = 0; + ret |= (value >> 24) & 0x000000ff; + ret |= (value >> 8) & 0x0000ff00; + ret |= (value << 8) & 0x00ff0000; + ret |= (value << 24) & 0xff000000; + return ret; +} + +static uint64_t endswap64(uint64_t value) { + uint64_t ret = 0; + ret |= (value >> 56) & 0x00000000000000ff; + ret |= (value >> 40) & 0x000000000000ff00; + ret |= (value >> 24) & 0x0000000000ff0000; + ret |= (value >> 8) & 0x00000000ff000000; + ret |= (value << 8) & 0x000000ff00000000; + ret |= (value << 24) & 0x0000ff0000000000; + ret |= (value << 40) & 0x00ff000000000000; + ret |= (value << 56) & 0xff00000000000000; + return ret; +} + +#ifdef __BYTE_ORDER__ + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define bigendian true +#else +#define bigendian false +#endif + +#else /* !__BYTE_ORDER__ */ + +static bool bigendian = false; + +#endif /* !__BYTE_ORDER__ */ + +#define ENDSWAP(VALUE) (bigendian ? ( \ + sizeof(VALUE) == 1 ? (VALUE) : \ + sizeof(VALUE) == 2 ? endswap16(VALUE) : \ + sizeof(VALUE) == 4 ? endswap32(VALUE) : \ + sizeof(VALUE) == 8 ? endswap64(VALUE) : (abort(), 1) \ +) : (VALUE)) + +static enum { + CACHE_CLEAN, + CACHE_DIRTY +} cache_state; +static uint64_t cached_block; +static uint8_t *cache = NULL; +static FILE *device = NULL; +static size_t block_size; + +static bool device_init(void) { + size_t guesses[] = { 512, 2048, 4096 }; + + for (size_t i = 0; i < sizeof(guesses) / sizeof(size_t); i++) { + void *tmp = realloc(cache, guesses[i]); + if (tmp == NULL) { + perror_wrap("error: device_init(): realloc()"); + return false; + } + cache = tmp; + + rewind(device); + + size_t ret = fread(cache, guesses[i], 1, device); + if (ret != 1) { + continue; + } + + block_size = guesses[i]; + + if (!quiet) { + fprintf(stderr, "Physical block size of %zu bytes.\n", block_size); + } + + cache_state = CACHE_CLEAN; + cached_block = 0; + return true; + } + + fprintf(stderr, "%s: error: device_init(): Couldn't determine block size of device.\n", program_name); + return false; +} + +static bool device_flush_cache(void) { + if (cache_state == CACHE_CLEAN) + return true; + + if (set_pos(device, cached_block * block_size) != 0) { + perror_wrap("error: device_flush_cache(): set_pos()"); + return false; + } + + size_t ret = fwrite(cache, block_size, 1, device); + if (ret != 1) { + if (ferror(device)) { + perror_wrap("error: device_flush_cache(): fwrite()"); + } + return false; + } + + cache_state = CACHE_CLEAN; + return true; +} + +static bool device_cache_block(uint64_t block) { + if (cached_block == block) + return true; + + if (cache_state == CACHE_DIRTY) { + if (!device_flush_cache()) + return false; + } + + if (set_pos(device, block * block_size) != 0) { + perror_wrap("error: device_cache_block(): set_pos()"); + return false; + } + + size_t ret = fread(cache, block_size, 1, device); + if (ret != 1) { + if (ferror(device)) { + perror_wrap("error: device_cache_block(): fread()"); + } + return false; + } + + cached_block = block; + + return true; +} + +struct uninstall_data { + void *data; + uint64_t loc; + uint64_t count; +}; + +#define UNINSTALL_DATA_MAX 256 + +static bool uninstalling = false; +static struct uninstall_data uninstall_data[UNINSTALL_DATA_MAX]; +static struct uninstall_data uninstall_data_rev[UNINSTALL_DATA_MAX]; +static uint64_t uninstall_data_i = 0; +static const char *uninstall_file = NULL; + +static void reverse_uninstall_data(void) { + for (size_t i = 0, j = uninstall_data_i - 1; i < uninstall_data_i; i++, j--) { + uninstall_data_rev[j] = uninstall_data[i]; + } + + memcpy(uninstall_data, uninstall_data_rev, uninstall_data_i * sizeof(struct uninstall_data)); +} + +static void free_uninstall_data(void) { + for (size_t i = 0; i < uninstall_data_i; i++) { + free(uninstall_data[i].data); + } +} + +static bool store_uninstall_data(const char *filename) { + if (!quiet) { + fprintf(stderr, "Storing uninstall data to file: `%s`...\n", filename); + } + + FILE *udfile = fopen(filename, "wb"); + if (udfile == NULL) { + perror_wrap("error: `%s`", filename); + goto error; + } + + if (fwrite(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) { + goto fwrite_error; + } + + for (size_t i = 0; i < uninstall_data_i; i++) { + if (fwrite(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) { + goto fwrite_error; + } + if (fwrite(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) { + goto fwrite_error; + } + if (fwrite(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) { + goto fwrite_error; + } + } + + fclose(udfile); + return true; + +fwrite_error: + perror_wrap("error: store_uninstall_data(): fwrite()"); + +error: + if (udfile != NULL) { + fclose(udfile); + } + return false; +} + +static bool load_uninstall_data(const char *filename) { + if (!quiet) { + fprintf(stderr, "Loading uninstall data from file: `%s`...\n", filename); + } + + FILE *udfile = fopen(filename, "rb"); + if (udfile == NULL) { + perror_wrap("error: `%s`", filename); + goto error; + } + + if (fread(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) { + goto fread_error; + } + + for (size_t i = 0; i < uninstall_data_i; i++) { + if (fread(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) { + goto fread_error; + } + if (fread(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) { + goto fread_error; + } + uninstall_data[i].data = malloc(uninstall_data[i].count); + if (uninstall_data[i].data == NULL) { + perror_wrap("error: load_uninstall_data(): malloc()"); + goto error; + } + if (fread(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) { + goto fread_error; + } + } + + fclose(udfile); + return true; + +fread_error: + perror_wrap("error: load_uninstall_data(): fread()"); + +error: + if (udfile != NULL) { + fclose(udfile); + } + return false; +} + +static bool _device_read(void *_buffer, uint64_t loc, size_t count) { + uint8_t *buffer = _buffer; + uint64_t progress = 0; + while (progress < count) { + uint64_t block = (loc + progress) / block_size; + + if (!device_cache_block(block)) { + return false; + } + + uint64_t chunk = count - progress; + uint64_t offset = (loc + progress) % block_size; + if (chunk > block_size - offset) + chunk = block_size - offset; + + memcpy(buffer + progress, &cache[offset], chunk); + progress += chunk; + } + + return true; +} + +static bool _device_write(const void *_buffer, uint64_t loc, size_t count) { + if (uninstalling) { + goto skip_save; + } + + if (uninstall_data_i >= UNINSTALL_DATA_MAX) { + fprintf(stderr, "%s: error: Too many uninstall data entries! Please report this bug upstream.\n", program_name); + return false; + } + + struct uninstall_data *ud = &uninstall_data[uninstall_data_i]; + + ud->data = malloc(count); + if (ud->data == NULL) { + perror_wrap("error: _device_write(): malloc()"); + return false; + } + + if (!_device_read(ud->data, loc, count)) { + return false; + } + + ud->loc = loc; + ud->count = count; + +skip_save:; + const uint8_t *buffer = _buffer; + uint64_t progress = 0; + while (progress < count) { + uint64_t block = (loc + progress) / block_size; + + if (!device_cache_block(block)) { + return false; + } + + uint64_t chunk = count - progress; + uint64_t offset = (loc + progress) % block_size; + if (chunk > block_size - offset) + chunk = block_size - offset; + + memcpy(&cache[offset], buffer + progress, chunk); + cache_state = CACHE_DIRTY; + progress += chunk; + } + + if (!uninstalling) { + uninstall_data_i++; + } + return true; +} + +static bool uninstall(bool quiet_arg) { + bool print_cache_flush_fail = false; + bool print_write_fail = false; + bool ret = true; + + uninstalling = true; + + cache_state = CACHE_CLEAN; + cached_block = (uint64_t)-1; + + for (size_t i = 0; i < uninstall_data_i; i++) { + struct uninstall_data *ud = &uninstall_data[i]; + bool retry = false; + while (!_device_write(ud->data, ud->loc, ud->count)) { + if (retry) { + fprintf(stderr, "%s: warning: Retry failed.\n", program_name); + print_write_fail = true; + break; + } + if (!quiet) { + fprintf(stderr, "%s: warning: Uninstall data index %zu failed to write, retrying...\n", program_name, i); + } + if (!device_flush_cache()) { + print_cache_flush_fail = true; + } + cache_state = CACHE_CLEAN; + cached_block = (uint64_t)-1; + retry = true; + } + } + + if (!device_flush_cache()) { + print_cache_flush_fail = true; + } + + if (print_write_fail) { + fprintf(stderr, "%s: error: Some data failed to be uninstalled correctly.\n", program_name); + ret = false; + } + + if (print_cache_flush_fail) { + fprintf(stderr, "%s: error: Device cache flush failure. Uninstall may be incomplete.\n", program_name); + ret = false; + } + + if (ret == true && !quiet && !quiet_arg) { + fprintf(stderr, "Uninstall data restored successfully.\n"); + } + + return ret; +} + +#define device_read(BUFFER, LOC, COUNT) \ + do { \ + if (!_device_read(BUFFER, LOC, COUNT)) \ + goto cleanup; \ + } while (0) + +#define device_write(BUFFER, LOC, COUNT) \ + do { \ + if (!_device_write(BUFFER, LOC, COUNT)) \ + goto cleanup; \ + } while (0) + +static void bios_install_usage(void) { + printf("usage: %s bios-install [GPT partition index]\n", program_name); + printf("\n"); + printf(" --force-mbr Force MBR detection to work even if the\n"); + printf(" safety checks fail (DANGEROUS!)\n"); + printf("\n"); + printf(" --uninstall Reverse the entire install procedure\n"); + printf("\n"); + printf(" --uninstall-data-file=\n"); + printf(" Set the input (for --uninstall) or output file\n"); + printf(" name of the file which contains uninstall data\n"); + printf("\n"); + printf(" --quiet Do not print verbose diagnostic messages\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); +} + +static int bios_install(int argc, char *argv[]) { + int ok = EXIT_FAILURE; + int force_mbr = 0; + bool uninstall_mode = false; + const uint8_t *bootloader_img = binary_limine_hdd_bin_data; + size_t bootloader_file_size = sizeof(binary_limine_hdd_bin_data); + uint8_t orig_mbr[70], timestamp[6]; + const char *part_ndx = NULL; + +#ifndef __BYTE_ORDER__ + uint32_t endcheck = 0x12345678; + uint8_t endbyte = *((uint8_t *)&endcheck); + bigendian = endbyte == 0x12; +#endif + + if (argc < 2) { + bios_install_usage(); +#ifdef IS_WINDOWS + system("pause"); +#endif + return EXIT_FAILURE; + } + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { + bios_install_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[i], "--quiet") == 0) { + quiet = true; + } else if (strcmp(argv[i], "--force-mbr") == 0) { + if (force_mbr && !quiet) { + fprintf(stderr, "%s: warning: --force-mbr already set.\n", program_name); + } + force_mbr = 1; + } else if (strcmp(argv[i], "--uninstall") == 0) { + if (uninstall_mode && !quiet) { + fprintf(stderr, "%s: warning: --uninstall already set.\n", program_name); + } + uninstall_mode = true; + } else if (memcmp(argv[i], "--uninstall-data-file=", 21) == 0) { + if (uninstall_file != NULL && !quiet) { + fprintf(stderr, "%s: warning: --uninstall-data-file already set. Overriding...\n", program_name); + } + uninstall_file = argv[i] + 21; + if (strlen(uninstall_file) == 0) { + fprintf(stderr, "%s: error: Uninstall data file has a zero-length name!\n", program_name); + return EXIT_FAILURE; + } + } else { + if (device != NULL) { // [GPT partition index] + part_ndx = argv[i]; // TODO: Make this non-positional? + } else if ((device = fopen(argv[i], "r+b")) == NULL) { // + perror_wrap("error: `%s`", argv[i]); + return EXIT_FAILURE; + } + } + } + + if (device == NULL) { + fprintf(stderr, "%s: error: No device specified\n", program_name); + bios_install_usage(); + return EXIT_FAILURE; + } + + if (!device_init()) { + goto uninstall_mode_cleanup; + } + + if (uninstall_mode) { + if (uninstall_file == NULL) { + fprintf(stderr, "%s: error: Uninstall mode set but no --uninstall-data-file=... passed.\n", program_name); + goto uninstall_mode_cleanup; + } + + if (!load_uninstall_data(uninstall_file)) { + goto uninstall_mode_cleanup; + } + + if (uninstall(false) == false) { + ok = EXIT_FAILURE; + } else { + ok = EXIT_SUCCESS; + } + goto uninstall_mode_cleanup; + } + + // Probe for GPT and logical block size + int gpt = 0; + struct gpt_table_header gpt_header; + uint64_t lb_guesses[] = { 512, 4096 }; + uint64_t lb_size = 0; + for (size_t i = 0; i < sizeof(lb_guesses) / sizeof(uint64_t); i++) { + device_read(&gpt_header, lb_guesses[i], sizeof(struct gpt_table_header)); + if (!strncmp(gpt_header.signature, "EFI PART", 8)) { + lb_size = lb_guesses[i]; + if (!force_mbr) { + gpt = 1; + if (!quiet) { + fprintf(stderr, "Installing to GPT. Logical block size of %" PRIu64 " bytes.\n", + lb_guesses[i]); + } + } else { + fprintf(stderr, "%s: error: Device has a valid GPT, refusing to force MBR.\n", program_name); + goto cleanup; + } + break; + } + } + + struct gpt_table_header secondary_gpt_header; + if (gpt) { + if (!quiet) { + fprintf(stderr, "Secondary header at LBA 0x%" PRIx64 ".\n", + ENDSWAP(gpt_header.alternate_lba)); + } + device_read(&secondary_gpt_header, lb_size * ENDSWAP(gpt_header.alternate_lba), + sizeof(struct gpt_table_header)); + if (!strncmp(secondary_gpt_header.signature, "EFI PART", 8)) { + if (!quiet) { + fprintf(stderr, "Secondary header valid.\n"); + } + } else { + fprintf(stderr, "%s: error: Secondary header not valid, aborting.\n", program_name); + goto cleanup; + } + } + + int mbr = 0; + if (gpt == 0) { + // Do all sanity checks on MBR + mbr = 1; + + uint8_t hint8 = 0; + uint16_t hint16 = 0; + uint32_t hint32 = 0; + + bool any_active = false; + + device_read(&hint8, 446, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 446, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 446 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 446 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + device_read(&hint8, 462, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 462, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 462 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 462 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + device_read(&hint8, 478, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 478, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 478 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 478 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + device_read(&hint8, 494, sizeof(uint8_t)); + if (hint8 != 0x00 && hint8 != 0x80) { + if (!force_mbr) { + mbr = 0; + } else { + hint8 &= 0x80; + device_write(&hint8, 494, sizeof(uint8_t)); + } + } + any_active = any_active || (hint8 & 0x80) != 0; + device_read(&hint8, 494 + 4, sizeof(uint8_t)); + if (hint8 != 0x00) { + device_read(&hint32, 494 + 8, sizeof(uint32_t)); + hint32 = ENDSWAP(hint32); + if (hint32 < 63) { + goto part_too_low; + } + } + + if (0) { +part_too_low: + fprintf(stderr, "%s: error: A partition's start sector is less than 63, aborting.\n", program_name); + goto cleanup; + } + + char hintc[64]; + device_read(hintc, 4, 8); + if (memcmp(hintc, "_ECH_FS_", 8) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 8); + device_write(hintc, 4, 8); + } + } + device_read(hintc, 3, 4); + if (memcmp(hintc, "NTFS", 4) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 4); + device_write(hintc, 3, 4); + } + } + device_read(hintc, 54, 3); + if (memcmp(hintc, "FAT", 3) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 5); + device_write(hintc, 54, 5); + } + } + device_read(hintc, 82, 3); + if (memcmp(hintc, "FAT", 3) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 5); + device_write(hintc, 82, 5); + } + } + device_read(hintc, 3, 5); + if (memcmp(hintc, "FAT32", 5) == 0) { + if (!force_mbr) { + mbr = 0; + } else { + memset(hintc, 0, 5); + device_write(hintc, 3, 5); + } + } + device_read(&hint16, 1080, sizeof(uint16_t)); + hint16 = ENDSWAP(hint16); + if (hint16 == 0xef53) { + if (!force_mbr) { + mbr = 0; + } else { + hint16 = 0; + hint16 = ENDSWAP(hint16); + device_write(&hint16, 1080, sizeof(uint16_t)); + } + } + + if (mbr && !any_active) { + if (!quiet) { + fprintf(stderr, "No active partition found, some systems may not boot.\n"); + fprintf(stderr, "Setting partition 1 as active to work around the issue...\n"); + } + hint8 = 0x80; + device_write(&hint8, 446, sizeof(uint8_t)); + } + } + + if (gpt == 0 && mbr == 0) { + fprintf(stderr, "error: Could not determine if the device has a valid partition table.\n"); + fprintf(stderr, " Please ensure the device has a valid MBR or GPT.\n"); + fprintf(stderr, " Alternatively, pass `--force-mbr` to override these checks.\n"); + fprintf(stderr, " **ONLY DO THIS AT YOUR OWN RISK, DATA LOSS MAY OCCUR!**\n"); + goto cleanup; + } + + size_t stage2_size = bootloader_file_size - 512; + + size_t stage2_sects = DIV_ROUNDUP(stage2_size, 512); + + uint16_t stage2_size_a = (stage2_sects / 2) * 512 + (stage2_sects % 2 ? 512 : 0); + uint16_t stage2_size_b = (stage2_sects / 2) * 512; + + // Default split of stage2 for MBR (consecutive in post MBR gap) + uint64_t stage2_loc_a = 512; + uint64_t stage2_loc_b = stage2_loc_a + stage2_size_a; + + if (gpt) { + if (part_ndx != NULL) { + uint32_t partition_num; + sscanf(part_ndx, "%" SCNu32, &partition_num); + partition_num--; + if (partition_num > ENDSWAP(gpt_header.number_of_partition_entries)) { + fprintf(stderr, "%s: error: Partition number is too large.\n", program_name); + goto cleanup; + } + + struct gpt_entry gpt_entry; + device_read(&gpt_entry, + (ENDSWAP(gpt_header.partition_entry_lba) * lb_size) + + (partition_num * ENDSWAP(gpt_header.size_of_partition_entry)), + sizeof(struct gpt_entry)); + + if (gpt_entry.unique_partition_guid[0] == 0 && + gpt_entry.unique_partition_guid[1] == 0) { + fprintf(stderr, "%s: error: No such partition: `%s`.\n", program_name, part_ndx); + goto cleanup; + } + + if (!quiet) { + fprintf(stderr, "GPT partition specified. Installing there instead of embedding.\n"); + } + + stage2_loc_a = ENDSWAP(gpt_entry.starting_lba) * lb_size; + stage2_loc_b = stage2_loc_a + stage2_size_a; + if (stage2_loc_b & (lb_size - 1)) + stage2_loc_b = (stage2_loc_b + lb_size) & ~(lb_size - 1); + } else { + if (!quiet) { + fprintf(stderr, "GPT partition NOT specified. Attempting GPT embedding.\n"); + } + + int64_t max_partition_entry_used = -1; + for (int64_t i = 0; i < (int64_t)ENDSWAP(gpt_header.number_of_partition_entries); i++) { + struct gpt_entry gpt_entry; + device_read(&gpt_entry, + (ENDSWAP(gpt_header.partition_entry_lba) * lb_size) + + (i * ENDSWAP(gpt_header.size_of_partition_entry)), + sizeof(struct gpt_entry)); + + if (gpt_entry.unique_partition_guid[0] != 0 || + gpt_entry.unique_partition_guid[1] != 0) { + if (i > max_partition_entry_used) + max_partition_entry_used = i; + } + } + + stage2_loc_a = (ENDSWAP(gpt_header.partition_entry_lba) + 32) * lb_size; + stage2_loc_a -= stage2_size_a; + stage2_loc_a &= ~(lb_size - 1); + stage2_loc_b = (ENDSWAP(secondary_gpt_header.partition_entry_lba) + 32) * lb_size; + stage2_loc_b -= stage2_size_b; + stage2_loc_b &= ~(lb_size - 1); + + size_t partition_entries_per_lb = + lb_size / ENDSWAP(gpt_header.size_of_partition_entry); + size_t new_partition_array_lba_size = + stage2_loc_a / lb_size - ENDSWAP(gpt_header.partition_entry_lba); + size_t new_partition_entry_count = + new_partition_array_lba_size * partition_entries_per_lb; + + if ((int64_t)new_partition_entry_count <= max_partition_entry_used) { + fprintf(stderr, "%s: error: Cannot embed because there are too many used partition entries.\n", program_name); + goto cleanup; + } + + if (!quiet) { + fprintf(stderr, "New maximum count of partition entries: %zu.\n", new_partition_entry_count); + } + + // Zero out unused partitions + void *empty = calloc(1, ENDSWAP(gpt_header.size_of_partition_entry)); + for (size_t i = max_partition_entry_used + 1; i < new_partition_entry_count; i++) { + device_write(empty, + ENDSWAP(gpt_header.partition_entry_lba) * lb_size + i * ENDSWAP(gpt_header.size_of_partition_entry), + ENDSWAP(gpt_header.size_of_partition_entry)); + } + for (size_t i = max_partition_entry_used + 1; i < new_partition_entry_count; i++) { + device_write(empty, + ENDSWAP(secondary_gpt_header.partition_entry_lba) * lb_size + i * ENDSWAP(secondary_gpt_header.size_of_partition_entry), + ENDSWAP(secondary_gpt_header.size_of_partition_entry)); + } + free(empty); + + uint8_t *partition_array = + malloc(new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry)); + if (partition_array == NULL) { + perror_wrap("error: bios_install(): malloc()"); + goto cleanup; + } + + device_read(partition_array, + ENDSWAP(gpt_header.partition_entry_lba) * lb_size, + new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry)); + + uint32_t crc32_partition_array = + crc32(partition_array, + new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry)); + + free(partition_array); + + gpt_header.partition_entry_array_crc32 = ENDSWAP(crc32_partition_array); + gpt_header.number_of_partition_entries = ENDSWAP(new_partition_entry_count); + gpt_header.crc32 = 0; + gpt_header.crc32 = crc32(&gpt_header, 92); + gpt_header.crc32 = ENDSWAP(gpt_header.crc32); + device_write(&gpt_header, + lb_size, + sizeof(struct gpt_table_header)); + + secondary_gpt_header.partition_entry_array_crc32 = ENDSWAP(crc32_partition_array); + secondary_gpt_header.number_of_partition_entries = + ENDSWAP(new_partition_entry_count); + secondary_gpt_header.crc32 = 0; + secondary_gpt_header.crc32 = crc32(&secondary_gpt_header, 92); + secondary_gpt_header.crc32 = ENDSWAP(secondary_gpt_header.crc32); + device_write(&secondary_gpt_header, + lb_size * ENDSWAP(gpt_header.alternate_lba), + sizeof(struct gpt_table_header)); + } + } else { + if (!quiet) { + fprintf(stderr, "Installing to MBR.\n"); + } + } + + if (!quiet) { + fprintf(stderr, "Stage 2 to be located at 0x%" PRIx64 " and 0x%" PRIx64 ".\n", + stage2_loc_a, stage2_loc_b); + } + + // Save original timestamp + device_read(timestamp, 218, 6); + + // Save the original partition table of the device + device_read(orig_mbr, 440, 70); + + // Write the bootsector from the bootloader to the device + device_write(&bootloader_img[0], 0, 512); + + // Write the rest of stage 2 to the device + device_write(&bootloader_img[512], stage2_loc_a, stage2_size_a); + device_write(&bootloader_img[512 + stage2_size_a], + stage2_loc_b, stage2_size - stage2_size_a); + + // Hardcode in the bootsector the location of stage 2 halves + stage2_size_a = ENDSWAP(stage2_size_a); + device_write(&stage2_size_a, 0x1a4 + 0, sizeof(uint16_t)); + stage2_size_b = ENDSWAP(stage2_size_b); + device_write(&stage2_size_b, 0x1a4 + 2, sizeof(uint16_t)); + stage2_loc_a = ENDSWAP(stage2_loc_a); + device_write(&stage2_loc_a, 0x1a4 + 4, sizeof(uint64_t)); + stage2_loc_b = ENDSWAP(stage2_loc_b); + device_write(&stage2_loc_b, 0x1a4 + 12, sizeof(uint64_t)); + + // Write back timestamp + device_write(timestamp, 218, 6); + + // Write back the saved partition table to the device + device_write(orig_mbr, 440, 70); + + if (!device_flush_cache()) + goto cleanup; + + if (!quiet) { + fprintf(stderr, "Reminder: Remember to copy the limine-bios.sys file in either\n" + " the root, /boot, /limine, or /boot/limine directories of\n" + " one of the partitions on the device, or boot will fail!\n"); + + fprintf(stderr, "Limine BIOS stages installed successfully!\n"); + } + + ok = EXIT_SUCCESS; + +cleanup: + reverse_uninstall_data(); + if (ok != EXIT_SUCCESS) { + // If we failed, attempt to reverse install process + fprintf(stderr, "%s: Install failed, undoing work...\n", program_name); + uninstall(true); + } else if (uninstall_file != NULL) { + store_uninstall_data(uninstall_file); + } +uninstall_mode_cleanup: + free_uninstall_data(); + if (cache) + free(cache); + if (device != NULL) + fclose(device); + + return ok; +} +#endif + +#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++" + +static void enroll_config_usage(void) { + printf("usage: %s enroll-config \n", program_name); + printf("\n"); + printf(" --reset Remove enrolled BLAKE2B, will not check config integrity\n"); + printf("\n"); + printf(" --quiet Do not print verbose diagnostic messages\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); +} + +static int enroll_config(int argc, char *argv[]) { + int ret = EXIT_FAILURE; + + char *bootloader = NULL; + FILE *bootloader_file = NULL; + bool quiet = false; + bool reset = false; + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { + enroll_config_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[i], "--quiet") == 0) { + remove_arg(&argc, argv, i); + quiet = true; + } else if (strcmp(argv[i], "--reset") == 0) { + remove_arg(&argc, argv, i); + reset = true; + } + } + + if (argc <= (reset ? 1 : 2)) { + enroll_config_usage(); +#ifdef IS_WINDOWS + system("pause"); +#endif + return EXIT_FAILURE; + } + + if (!reset && strlen(argv[2]) != 128) { + fprintf(stderr, "%s: error: BLAKE2B specified is not 128 characters long.\n", program_name); + goto cleanup; + } + + bootloader_file = fopen(argv[1], "r+b"); + if (bootloader_file == NULL) { + perror_wrap("error: `%s`", argv[1]); + goto cleanup; + } + + if (fseek(bootloader_file, 0, SEEK_END) != 0) { + perror_wrap("error: enroll_config(): fseek()"); + goto cleanup; + } + size_t bootloader_size = ftell(bootloader_file); + rewind(bootloader_file); + + bootloader = malloc(bootloader_size); + if (bootloader == NULL) { + perror_wrap("error: enroll_config(): malloc()"); + goto cleanup; + } + + if (fread(bootloader, bootloader_size, 1, bootloader_file) != 1) { + perror_wrap("error: enroll_config(): fread()"); + goto cleanup; + } + + char *checksum_loc = NULL; + size_t checked_count = 0; + const char *config_b2sum_sign = CONFIG_B2SUM_SIGNATURE; + for (size_t i = 0; i < bootloader_size - ((sizeof(CONFIG_B2SUM_SIGNATURE) - 1) + 128) + 1; i++) { + if (bootloader[i] != config_b2sum_sign[checked_count]) { + checked_count = 0; + continue; + } + + checked_count++; + + if (checked_count == sizeof(CONFIG_B2SUM_SIGNATURE) - 1) { + checksum_loc = &bootloader[i + 1]; + break; + } + } + + if (checksum_loc == NULL) { + fprintf(stderr, "%s: error: Checksum location not found in provided executable.\n", program_name); + goto cleanup; + } + + if (!reset) { + memcpy(checksum_loc, argv[2], 128); + } else { + memset(checksum_loc, '0', 128); + } + + if (fseek(bootloader_file, 0, SEEK_SET) != 0) { + perror_wrap("error: enroll_config(): fseek()"); + goto cleanup; + } + if (fwrite(bootloader, bootloader_size, 1, bootloader_file) != 1) { + perror_wrap("error: enroll_config(): fwrite()"); + goto cleanup; + } + + if (!quiet) { + fprintf(stderr, "Config file BLAKE2B successfully %s!\n", reset ? "reset" : "enrolled"); + } + ret = EXIT_SUCCESS; + +cleanup: + if (bootloader != NULL) { + free(bootloader); + } + if (bootloader_file != NULL) { + fclose(bootloader_file); + } + return ret; +} + +#define LIMINE_VERSION "7.13.3" +#define LIMINE_COPYRIGHT "Copyright (C) 2019-2024 mintsuki and contributors." + +static void version_usage(void) { + printf("usage: %s version [options...]\n", program_name); + printf("\n"); + printf(" --version-only Only print the version number without licensing info\n"); + printf(" and other distractions\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); +} + +static int version(int argc, char *argv[]) { + if (argc >= 2) { + if (strcmp(argv[1], "--help") == 0) { + version_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "--version-only") == 0) { + puts(LIMINE_VERSION); + return EXIT_SUCCESS; + } + } + + puts("Limine " LIMINE_VERSION); + puts(LIMINE_COPYRIGHT); + puts("Limine is distributed under the terms of the BSD-2-Clause license."); + puts("There is ABSOLUTELY NO WARRANTY, to the extent permitted by law."); + return EXIT_SUCCESS; +} + +static void general_usage(void) { + printf("usage: %s \n", program_name); + printf("\n"); + printf(" --print-datadir Print the directory containing the bootloader files\n"); + printf("\n"); + printf(" --version Print the Limine version (like the `version` command)\n"); + printf("\n"); + printf(" --help | -h Display this help message\n"); + printf("\n"); + printf("Commands: `help`, `version`, `bios-install`, `enroll-config`\n"); + printf("Use `--help` after specifying the command for command-specific help.\n"); +} + +static int print_datadir(void) { +#ifdef LIMINE_DATADIR + puts(LIMINE_DATADIR); + return EXIT_SUCCESS; +#else + fprintf(stderr, "%s: error: Cannot print datadir for `limine` built out-of-tree.\n", program_name); + return EXIT_FAILURE; +#endif +} + +int main(int argc, char *argv[]) { + program_name = argv[0]; + + if (argc <= 1) { + general_usage(); + return EXIT_FAILURE; + } + + if (strcmp(argv[1], "help") == 0 + || strcmp(argv[1], "--help") == 0 + || strcmp(argv[1], "-h") == 0) { + general_usage(); + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "bios-install") == 0) { +#ifndef LIMINE_NO_BIOS + return bios_install(argc - 1, &argv[1]); +#else + fprintf(stderr, "%s: error: Limine has been compiled without BIOS support.\n", program_name); + return EXIT_FAILURE; +#endif + } else if (strcmp(argv[1], "enroll-config") == 0) { + return enroll_config(argc - 1, &argv[1]); + } else if (strcmp(argv[1], "--print-datadir") == 0) { + return print_datadir(); + } else if (strcmp(argv[1], "version") == 0 + || strcmp(argv[1], "--version") == 0) { + return version(argc - 1, &argv[1]); + } + + general_usage(); + return EXIT_FAILURE; +} diff --git a/FloridOS/limine/limine.exe b/FloridOS/limine/limine.exe new file mode 100644 index 0000000..ccdd89a Binary files /dev/null and b/FloridOS/limine/limine.exe differ diff --git a/FloridOS/limine/limine.h b/FloridOS/limine/limine.h new file mode 100644 index 0000000..63e8422 --- /dev/null +++ b/FloridOS/limine/limine.h @@ -0,0 +1,609 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2024 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIMINE_H +#define LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_REQUESTS_START_MARKER \ + uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ + 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; +#define LIMINE_REQUESTS_END_MARKER \ + uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; + +#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Firmware type */ + +#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } + +#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 +#define LIMINE_FIRMWARE_TYPE_UEFI32 1 +#define LIMINE_FIRMWARE_TYPE_UEFI64 2 + +struct limine_firmware_type_response { + uint64_t revision; + uint64_t firmware_type; +}; + +struct limine_firmware_type_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_firmware_type_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t max_mode; + uint64_t min_mode; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t reserved1; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) +#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FloridOS/linker.ld b/FloridOS/linker.ld new file mode 100644 index 0000000..89b75ce --- /dev/null +++ b/FloridOS/linker.ld @@ -0,0 +1,11 @@ +ENTRY(_start) + +SECTIONS +{ + . = 0xffffffff80000000; + + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + .data : { *(.data .data.*) } + .bss : { *(.bss .bss.*) *(COMMON) } +} \ No newline at end of file diff --git a/FloridOS/src/drivers/io.h b/FloridOS/src/drivers/io.h new file mode 100644 index 0000000..d96de11 --- /dev/null +++ b/FloridOS/src/drivers/io.h @@ -0,0 +1,11 @@ +#ifndef IO_H +#define IO_H +#include + +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + __asm__ volatile ( "inb %w1, %b0" : "=a"(ret) : "Nd"(port) : "memory"); + return ret; +} + +#endif \ No newline at end of file diff --git a/FloridOS/src/drivers/keyboard.c b/FloridOS/src/drivers/keyboard.c new file mode 100644 index 0000000..fb25ab4 --- /dev/null +++ b/FloridOS/src/drivers/keyboard.c @@ -0,0 +1,39 @@ +#include "io.h" +#include "tty.h" + +// The Scan Code Map - Every key on the keyboard! +char kbd_map[] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ' +}; + +static uint8_t last_scancode = 0; + +void update_keyboard() { + // Check if the keyboard has data ready (Status Port 0x64, Bit 0) + if (inb(0x64) & 1) { + uint8_t scancode = inb(0x60); + + // If the scancode is the SAME as the last one, skip it + // This prevents one tap from typing 50 letters on your fast laptop + if (scancode == last_scancode) { + return; + } + + last_scancode = scancode; + + // Key Pressed (scancode < 0x80) + if (scancode < 0x80) { + char c = kbd_map[scancode]; + if (c > 0) { + tty_putchar(c); + } + } else { + // Key Released (scancode >= 0x80) + // We reset last_scancode so you can press the same key again later + last_scancode = 0; + } + } +} \ No newline at end of file diff --git a/FloridOS/src/drivers/keyboard.h b/FloridOS/src/drivers/keyboard.h new file mode 100644 index 0000000..8512b99 --- /dev/null +++ b/FloridOS/src/drivers/keyboard.h @@ -0,0 +1,9 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include + +// This tells the rest of the OS that this function exists in keyboard.c +void update_keyboard(void); + +#endif \ No newline at end of file diff --git a/FloridOS/src/drivers/terminal.c b/FloridOS/src/drivers/terminal.c new file mode 100644 index 0000000..a15fa71 --- /dev/null +++ b/FloridOS/src/drivers/terminal.c @@ -0,0 +1,53 @@ +#include "drivers/terminal.h" + +#define MAX_COLS 80 +#define MAX_ROWS 25 + +static uint16_t terminal_buffer[MAX_ROWS * MAX_COLS]; +static int cursor_x = 0, cursor_y = 0; + +// To reach 1000 lines, we implement a full 'scroll' function +void terminal_scroll() { + for (int i = 0; i < MAX_ROWS - 1; i++) { + for (int j = 0; j < MAX_COLS; j++) { + terminal_buffer[i * MAX_COLS + j] = terminal_buffer[(i + 1) * MAX_COLS + j]; + } + } + // Clear the last line + for (int j = 0; j < MAX_COLS; j++) { + terminal_buffer[(MAX_ROWS - 1) * MAX_COLS + j] = ' '; + } + cursor_y = MAX_ROWS - 1; +} + +void terminal_putchar(char c) { + if (c == '\n') { + cursor_x = 0; + cursor_y++; + } else { + terminal_buffer[cursor_y * MAX_COLS + cursor_x] = c; + cursor_x++; + } + + if (cursor_x >= MAX_COLS) { + cursor_x = 0; + cursor_y++; + } + + if (cursor_y >= MAX_ROWS) { + terminal_scroll(); + } + // Now call your draw_char function to update the pixels... +} + +void terminal_write(const char* data, size_t size) { + for (size_t i = 0; i < size; i++) { + terminal_putchar(data[i]); + } +} + +void terminal_writestring(const char* data) { + size_t len = 0; + while (data[len]) len++; + terminal_write(data, len); +} \ No newline at end of file diff --git a/FloridOS/src/drivers/terminal.h b/FloridOS/src/drivers/terminal.h new file mode 100644 index 0000000..0c1b477 --- /dev/null +++ b/FloridOS/src/drivers/terminal.h @@ -0,0 +1,13 @@ +#ifndef TERMINAL_H +#define TERMINAL_H + +#include +#include + +// Example: Define your terminal functions here +void terminal_initialize(void); +void terminal_putchar(char c); +void terminal_write(const char* data, size_t size); +void terminal_writestring(const char* data); + +#endif \ No newline at end of file diff --git a/FloridOS/src/drivers/tty.c b/FloridOS/src/drivers/tty.c new file mode 100644 index 0000000..d20d48c --- /dev/null +++ b/FloridOS/src/drivers/tty.c @@ -0,0 +1,64 @@ +#include "tty.h" + +// The state of our terminal +static struct tty_framebuffer *fb; +static uint32_t cursor_x = 20; +static uint32_t cursor_y = 20; +static uint32_t fg_color; +static uint32_t bg_color; + +// --- 8x8 BITMAP FONT --- +// This is a basic VGA font. Each byte is one row of pixels. +// This is where your line count starts climbing! +uint8_t font[128][8] = { + [0x20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Space + ['!'] = {0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00}, + ['A'] = {0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00}, + ['B'] = {0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00}, + ['C'] = {0x3C, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3C, 0x00}, + ['D'] = {0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00}, + ['E'] = {0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x7E, 0x00}, + ['F'] = {0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x06, 0x00}, + ['G'] = {0x3C, 0x66, 0x06, 0x76, 0x66, 0x66, 0x3C, 0x00}, + ['H'] = {0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00}, + ['I'] = {0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, + ['L'] = {0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00}, + ['O'] = {0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, + ['R'] = {0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00}, + ['S'] = {0x3C, 0x66, 0x06, 0x3C, 0x60, 0x66, 0x3C, 0x00}, + // (Note: You can add more characters here to hit 1,000 lines!) +}; + +void tty_init(struct tty_framebuffer *target, uint32_t fg, uint32_t bg) { + fb = target; + fg_color = fg; + bg_color = bg; +} + +void tty_draw_char(char c, uint32_t x, uint32_t y) { + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + // Changed from (1 << j) to (1 << (7 - j)) or vice versa + // Try this one specifically for VirtualBox: + if (font[(uint8_t)c][i] & (0x80 >> j)) { + fb->address[(y + i) * (fb->pitch / 4) + (x + j)] = fg_color; + } + } + } +} + +void tty_putchar(char c) { + if (c == '\n') { + cursor_x = 20; + cursor_y += 12; + return; + } + tty_draw_char(c, cursor_x, cursor_y); + cursor_x += 9; // Space between characters +} + +void tty_print(const char *str) { + for (size_t i = 0; str[i] != '\0'; i++) { + tty_putchar(str[i]); + } +} \ No newline at end of file diff --git a/FloridOS/src/drivers/tty.h b/FloridOS/src/drivers/tty.h new file mode 100644 index 0000000..40245d1 --- /dev/null +++ b/FloridOS/src/drivers/tty.h @@ -0,0 +1,29 @@ +#ifndef TTY_H +#define TTY_H + +#include +#include + +// This struct is a copy of the one in kernel.c so tty.c knows how to draw +struct tty_framebuffer { + uint32_t *address; + uint64_t width; + uint64_t height; + uint64_t pitch; +}; + +// --- TTY FUNCTIONS --- + +// Initializes the terminal with a framebuffer and colors +void tty_init(struct tty_framebuffer *fb, uint32_t fg, uint32_t bg); + +// Puts a single character on the screen +void tty_putchar(char c); + +// Prints a whole string (like your old writestring) +void tty_print(const char *str); + +// Clears the screen to the background color +void tty_clear(); + +#endif \ No newline at end of file diff --git a/FloridOS/src/kernel.c b/FloridOS/src/kernel.c new file mode 100644 index 0000000..cca1a1a --- /dev/null +++ b/FloridOS/src/kernel.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include "limine.h" +#include "drivers/tty.h" +#include "drivers/io.h" +#include "drivers/keyboard.h" + +// --- DELAY FUNCTION --- +// This handles the 5-second "Ourple" splash screen +void delay(uint64_t counts) { + for (volatile uint64_t i = 0; i < counts; i++) { + __asm__("nop"); + } +} + +// --- LIMINE REQUESTS --- +static volatile struct limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST, + .revision = 0 +}; + +// --- MATERIAL 3 COLOR PALETTE --- +#define M3_SURFACE 0x1C1B1F +#define M3_PRIMARY 0xD0BCFF +#define M3_PURPLE_ACCENT 0x381E72 + +// --- GRAPHICS STRUCTURE --- +struct framebuffer { + uint32_t *address; + uint64_t width; + uint64_t height; + uint64_t pitch; +}; + +// Function to draw a single pixel +void put_pixel(struct framebuffer *fb, uint32_t x, uint32_t y, uint32_t color) { + if (x >= fb->width || y >= fb->height) return; + fb->address[y * (fb->pitch / 4) + x] = color; +} + +// Function to draw a rectangle +void draw_rect(struct framebuffer *fb, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color) { + for (uint32_t i = 0; i < w; i++) { + for (uint32_t j = 0; j < h; j++) { + put_pixel(fb, x + i, y + j, color); + } + } +} + +// --- SYSTEM TABLES (GDT) --- +struct gdt_entry { + uint16_t limit_low; + uint16_t base_low; + uint8_t base_middle; + uint8_t access; + uint8_t granularity; + uint8_t base_high; +} __attribute__((packed)); + +struct gdt_ptr { + uint16_t limit; + uint64_t base; +} __attribute__((packed)); + +struct gdt_entry gdt[3]; +struct gdt_ptr gdt_p; + +void init_gdt() { + gdt[0] = (struct gdt_entry){0, 0, 0, 0, 0, 0}; // Null + gdt[1] = (struct gdt_entry){0, 0, 0, 0x9A, 0x20, 0}; // Code + gdt[2] = (struct gdt_entry){0, 0, 0, 0x92, 0, 0}; // Data + + gdt_p.limit = (sizeof(struct gdt_entry) * 3) - 1; + gdt_p.base = (uint64_t)&gdt; + __asm__ volatile("lgdt %0" : : "m"(gdt_p)); +} + +// --- KERNEL ENTRY POINT --- +void _start(void) { + // 1. Check if we have a screen + if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) { + __asm__("hlt"); + } + + struct limine_framebuffer *fb_info = framebuffer_request.response->framebuffers[0]; + struct framebuffer fb = { + .address = fb_info->address, + .width = fb_info->width, + .height = fb_info->height, + .pitch = fb_info->pitch + }; + + // 2. Setup CPU state + init_gdt(); + + // 3. THE 5-SECOND OURPLE INTRO + draw_rect(&fb, 0, 0, fb.width, fb.height, M3_PURPLE_ACCENT); + delay(800000000); // Wait 5 seconds + + // 4. THE MATERIAL 3 UI + draw_rect(&fb, 0, 0, fb.width, fb.height, M3_SURFACE); // Dark background + + // Draw the Pastel Purple Card + uint32_t cw = 400; uint32_t ch = 200; + draw_rect(&fb, (fb.width/2)-(cw/2), (fb.height/2)-(ch/2), cw, ch, M3_PRIMARY); + +// ... (Your existing rect drawing code) ... + + // 5. BOOT THE TTY + // We pass the fb address, White text (0xFFFFFF), and Dark background + tty_init((struct tty_framebuffer*)&fb, 0xFFFFFF, M3_SURFACE); + + + // 6. SAY HELLO! + tty_print("FLORID OS BOOTED\n"); + tty_print("READY_"); + + + for (;;) { + // Check Status Register (Port 0x64) + // Bit 0 (0x01) tells us if a key is waiting + if (inb(0x64) & 0x01) { + update_keyboard(); + } + + // Give VirtualBox a tiny rest so it doesn't lag the host + for(volatile int i = 0; i < 1000; i++); + __asm__("pause"); + } +} \ No newline at end of file diff --git a/FloridOS/src/kernel.h b/FloridOS/src/kernel.h new file mode 100644 index 0000000..e69de29 diff --git a/FloridOS/src/limine.h b/FloridOS/src/limine.h new file mode 100644 index 0000000..63e8422 --- /dev/null +++ b/FloridOS/src/limine.h @@ -0,0 +1,609 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2024 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIMINE_H +#define LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_REQUESTS_START_MARKER \ + uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ + 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; +#define LIMINE_REQUESTS_END_MARKER \ + uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; + +#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Firmware type */ + +#define LIMINE_FIRMWARE_TYPE_REQUEST { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 } + +#define LIMINE_FIRMWARE_TYPE_X86BIOS 0 +#define LIMINE_FIRMWARE_TYPE_UEFI32 1 +#define LIMINE_FIRMWARE_TYPE_UEFI64 2 + +struct limine_firmware_type_response { + uint64_t revision; + uint64_t firmware_type; +}; + +struct limine_firmware_type_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_firmware_type_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_X86_64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_AARCH64_4LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_MIN LIMINE_PAGING_MODE_RISCV_SV39 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t max_mode; + uint64_t min_mode; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t reserved1; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) +#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FloridOS/src/limine.h.1 b/FloridOS/src/limine.h.1 new file mode 100644 index 0000000..b7baa79 --- /dev/null +++ b/FloridOS/src/limine.h.1 @@ -0,0 +1,578 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2023 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LIMINE_H +#define _LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; + uint64_t flags; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t flags; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t gic_iface_no; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FloridOS/src/shell/commands.c b/FloridOS/src/shell/commands.c new file mode 100644 index 0000000..2f2d601 --- /dev/null +++ b/FloridOS/src/shell/commands.c @@ -0,0 +1,69 @@ +#include "shell.h" +#include "drivers/terminal.h" + +/* --- Utilities --- */ + +int strcmp(const char *s1, const char *s2) { + while (*s1 && (*s1 == *s2)) { + s1++; s2++; + } + return *(const unsigned char *)s1 - *(const unsigned char *)s2; +} + +int startswith(const char *str, const char *prefix) { + while (*prefix) { + if (*prefix++ != *str++) return 0; + } + return 1; +} + +/* --- Command Handlers --- */ + +void run_mofi() { + terminal_writestring("Entering MOFI editor...\n"); +} + +void handle_fds() { + terminal_writestring("Searching Florid Root...\n"); + terminal_writestring("/boot /sys /kernel /mofi_data\n"); +} + +void handle_obliterate(char* target) { + terminal_writestring("OBLITERATING: "); + terminal_writestring(target); + terminal_writestring("... SUCCESS.\n"); +} + +void handle_install() { + terminal_writestring("Searching for target disk...\n"); + terminal_writestring("Formatting /dev/sda as FloridFS...\n"); + terminal_writestring("Copying kernel bytes... [##########] 100%\n"); + terminal_writestring("Installation complete. Remove Live CD and reboot.\n"); +} + +/* --- The Interpreter (The If/Else Chain) --- */ + +void interpret_command(char* cmd) { + if (strcmp(cmd, "fds") == 0) { + handle_fds(); + } + else if (strcmp(cmd, "frua") == 0) { + terminal_writestring("ROOT ACCESS GRANTED.\n"); + } + else if (strcmp(cmd, "mofi") == 0) { + run_mofi(); + } + else if (strcmp(cmd, "install") == 0) { + handle_install(); + } + else if (startswith(cmd, "obliterate ")) { + handle_obliterate(cmd + 11); + } + else { + terminal_writestring("Unknown command. Try 'fds' or 'install'.\n"); + } +} + +void shell_init(void) { + terminal_writestring("Florid Shell Initialized.\n"); +} \ No newline at end of file diff --git a/FloridOS/src/shell/shell.h b/FloridOS/src/shell/shell.h new file mode 100644 index 0000000..fdc30d2 --- /dev/null +++ b/FloridOS/src/shell/shell.h @@ -0,0 +1,7 @@ +#ifndef SHELL_H +#define SHELL_H + +void shell_init(void); +void interpret_command(char* input); + +#endif \ No newline at end of file