diff --git a/.vscode/settings.json b/.vscode/settings.json index d876addd..9d06ecab 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,94 @@ "--background-index", "--compile-commands-dir=${workspaceFolder}/targets/cli/build" ], - "editor.tabSize": 2 + "editor.tabSize": 2, + "files.associations": { + "vector": "cpp", + "memory": "cpp", + "chrono": "cpp", + "variant": "cpp", + "mutex": "cpp", + "deque": "cpp", + "array": "cpp", + "ranges": "cpp", + "span": "cpp", + "xstring": "cpp", + "xutility": "cpp", + "algorithm": "cpp", + "any": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "filesystem": "cpp", + "format": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "functional": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "locale": "cpp", + "map": "cpp", + "new": "cpp", + "numeric": "cpp", + "optional": "cpp", + "ostream": "cpp", + "queue": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "set": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "utility": "cpp", + "valarray": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xtr1common": "cpp", + "xtree": "cpp" + } } \ No newline at end of file diff --git a/cspot/include/CSpotContext.h b/cspot/include/CSpotContext.h index d4fdde84..d39f7dc3 100644 --- a/cspot/include/CSpotContext.h +++ b/cspot/include/CSpotContext.h @@ -2,8 +2,10 @@ #include #include +#include //for random_device and default_random_engine #include "Crypto.h" +#include "EventManager.h" #include "LoginBlob.h" #include "MercurySession.h" #include "TimeProvider.h" @@ -35,6 +37,9 @@ struct Context { std::shared_ptr timeProvider; std::shared_ptr session; + std::shared_ptr playbackMetrics; + std::random_device rd; + std::default_random_engine rng; std::string getCredentialsJson() { #ifdef BELL_ONLY_CJSON cJSON* json_obj = cJSON_CreateObject(); @@ -66,8 +71,10 @@ struct Context { std::shared_ptr blob) { auto ctx = std::make_shared(); ctx->timeProvider = std::make_shared(); + ctx->rng = std::default_random_engine{ctx->rd()}; ctx->session = std::make_shared(ctx->timeProvider); + ctx->playbackMetrics = std::make_shared(ctx); ctx->config.deviceId = blob->getDeviceId(); ctx->config.deviceName = blob->getDeviceName(); ctx->config.authData = blob->authData; diff --git a/cspot/include/ConstantParameters.h b/cspot/include/ConstantParameters.h index 12ebac30..f57bc717 100644 --- a/cspot/include/ConstantParameters.h +++ b/cspot/include/ConstantParameters.h @@ -12,6 +12,6 @@ const char* const brandName = "cspot"; const char* const versionString = "cspot-1.1"; const char* const protocolVersion = "2.7.1"; const char* const defaultDeviceName = "CSpot"; -const char* const swVersion = "1.0.0"; +const char* const swVersion = "1.1.0"; } // namespace cspot \ No newline at end of file diff --git a/cspot/include/DeviceStateHandler.h b/cspot/include/DeviceStateHandler.h new file mode 100644 index 00000000..28b23dc6 --- /dev/null +++ b/cspot/include/DeviceStateHandler.h @@ -0,0 +1,110 @@ +/** + * TO DO + * + * autoplay doesn't work for episodes + * + */ +#pragma once + +#include // for uint8_t, uint32_t +#include //for deque.. +#include //for function +#include // for shared_ptr +#include // for string +#include // for pair +#include // for variant +#include // for vector + +#include "PlayerContext.h" // for PlayerContext::resolveTracklist, jsonToTracklist... +#include "TrackPlayer.h" // for TrackPlayer +#include "TrackQueue.h" +#include "TrackReference.h" +#include "protobuf/connect.pb.h" // for PutStateRequest, DeviceState, PlayerState... + +namespace cspot { +struct Context; +struct PlayerContext; + +class DeviceStateHandler { + public: + //Command Callback Structure + enum CommandType { + STOP, + PLAY, + PAUSE, + DISC, + DEPLETED, + FLUSH, + PLAYBACK_START, + PLAYBACK, + SKIP_NEXT, + SKIP_PREV, + SEEK, + SET_SHUFFLE, + SET_REPEAT, + VOLUME, + TRACK_INFO, + }; + + typedef std::variant, int32_t, bool> + CommandData; + + struct Command { + CommandType commandType; + CommandData data; + }; + + typedef std::function StateCallback; + + DeviceStateHandler(std::shared_ptr); + ~DeviceStateHandler(); + + void disconnect(); + + void putDeviceState(PutStateReason member_type = + PutStateReason::PutStateReason_PLAYER_STATE_CHANGED); + void putPlayerState(PutStateReason member_type = + PutStateReason::PutStateReason_PLAYER_STATE_CHANGED); + void handleConnectState(); + void sendCommand(CommandType, CommandData data = {}); + + Device device = Device_init_zero; + + std::vector currentTracks = {}; + StateCallback stateCallback; + + uint64_t started_playing_at = 0; + uint32_t last_message_id = -1; + uint8_t offset = 0; + int64_t offsetFromStartInMillis = 0; + + bool is_active = false; + bool reloadPreloadedTracks = true; + bool needsToBeSkipped = true; + bool playerStateChanged = false; + + std::shared_ptr trackPlayer; + std::shared_ptr trackQueue; + std::shared_ptr ctx; + + private: + std::shared_ptr playerContext; + + std::pair*> queuePacket = { + &offset, ¤tTracks}; + std::vector> metadata_map = {}; + std::vector> context_metadata_map = {}; + std::mutex playerStateMutex; + std::string context_uri, context_url; + void parseCommand(std::vector& data); + void skip(CommandType dir, bool notify); + + void unreference(char* string) { + if (string != NULL) + free(string); + string = NULL; + } + + static void reloadTrackList(void*); +}; +} // namespace cspot \ No newline at end of file diff --git a/cspot/include/EventManager.h b/cspot/include/EventManager.h new file mode 100644 index 00000000..975c849c --- /dev/null +++ b/cspot/include/EventManager.h @@ -0,0 +1,121 @@ +#pragma once + +#include // for uint8_t, uint32_t +#include //for sort +#include // for shared_ptr +#include // for string +#include // for vector + +namespace cspot { +struct Context; +class QueuedTrack; + +struct TrackInterval { + uint64_t start; + uint64_t end; + uint64_t position; + uint64_t length; + + TrackInterval(); + TrackInterval(uint64_t start, uint64_t position) { + this->start = start; + this->position = position; + } +}; + +struct skip { + uint8_t count = 0; + uint64_t amount = 0; + + void add(uint64_t amount) { + this->amount += amount; + count++; + } +}; + +class TrackMetrics { + public: + TrackMetrics(std::shared_ptr ctx, uint64_t pos = 0); + + std::shared_ptr currentInterval; + uint64_t longestInterval = 0, totalAmountOfPlayTime = 0, + totalMsOfPlayedTrack = 0, totalAmountPlayed = 0, audioKeyTime = 0, + trackHeaderTime = 0, written_bytes = 0, track_size = 0, + timestamp = 0, trackLatency = 0; + std::vector> intervals; + skip skipped_backward, skipped_forward; + + void newPosition(uint64_t pos); + void endInterval(uint64_t pos); + void pauseInterval(uint64_t pos, bool pause); + void endTrack(); + void startTrack(); + void startTrackDecoding(); + void startTrackPlaying(uint64_t pos); + uint64_t getPosition(bool paused = false); + + private: + std::shared_ptr ctx; + std::vector> addInterval( + std::vector>& intervals, + std::pair newInterval) { + // Add the new interval to the list of intervals + intervals.push_back(newInterval); + + // Sort intervals by starting time + std::sort(intervals.begin(), intervals.end()); + + // Result vector to hold merged intervals + std::vector> merged; + + // Iterate over intervals to merge overlapping ones + for (const auto& interval : intervals) { + // If merged is empty or current interval does not overlap with the previous one + if (merged.empty() || merged.back().second < interval.first) { + merged.push_back(interval); + } else { + // If it overlaps, merge the intervals + merged.back().second = std::max(merged.back().second, interval.second); + } + } + + return merged; + } +}; +class PlaybackMetrics { + private: + std::shared_ptr ctx; + uint32_t seqNum = 0; + size_t timestamp; + + std::string get_source_from_context(); + std::string get_end_source(); + + void append(std::vector* data, std::string to_do) { + data->insert(data->end(), to_do.begin(), to_do.end()); + data->push_back(9); + } + + public: + PlaybackMetrics(std::shared_ptr ctx) { this->ctx = ctx; } + enum reason { + TRACK_DONE, + TRACK_ERROR, + FORWARD_BTN, + BACKWARD_BTN, + END_PLAY, + PLAY_BTN, + CLICK_ROW, + LOGOUT, + APP_LOAD, + REMOTE, + UNKNOWN + } end_reason = UNKNOWN, + start_reason = UNKNOWN, nested_reason = UNKNOWN; + + std::string context_uri, correlation_id, start_source, end_source; + std::shared_ptr trackMetrics; + + std::vector sendEvent(std::shared_ptr track); +}; +} // namespace cspot \ No newline at end of file diff --git a/cspot/include/MercurySession.h b/cspot/include/MercurySession.h index de53dd2a..4359e0a0 100644 --- a/cspot/include/MercurySession.h +++ b/cspot/include/MercurySession.h @@ -27,7 +27,8 @@ class MercurySession : public bell::Task, public cspot::Session { struct Response { Header mercuryHeader; DataParts parts; - bool fail; + int64_t sequenceId; + bool fail = true; }; typedef std::function ResponseCallback; typedef std::function&)> @@ -39,7 +40,9 @@ class MercurySession : public bell::Task, public cspot::Session { UNSUB = 0xb4, SUBRES = 0xb5, SEND = 0xb2, - GET = 0xFF, // Shitty workaround, it's value is actually same as SEND + GET = 0xFF, // Shitty workaround, it's value is actually same as SEND + POST = 0xb6, //?? + PUT = 0xb7, //?? PING = 0x04, PONG_ACK = 0x4a, AUDIO_CHUNK_REQUEST_COMMAND = 0x08, @@ -57,14 +60,16 @@ class MercurySession : public bell::Task, public cspot::Session { }; std::unordered_map RequestTypeMap = { - {RequestType::GET, "GET"}, - {RequestType::SEND, "SEND"}, - {RequestType::SUB, "SUB"}, - {RequestType::UNSUB, "UNSUB"}, + {RequestType::GET, "GET"}, {RequestType::SEND, "SEND"}, + {RequestType::SUB, "SUB"}, {RequestType::UNSUB, "UNSUB"}, + {RequestType::POST, "POST"}, {RequestType::PUT, "PUT"}, }; void handlePacket(); + void addSubscriptionListener(const std::string& uri, + ResponseCallback subscription); + uint64_t executeSubscription(RequestType type, const std::string& uri, ResponseCallback callback, ResponseCallback subscription, DataParts& parts); @@ -114,7 +119,7 @@ class MercurySession : public bell::Task, public cspot::Session { void reconnect(); std::unordered_map callbacks; - std::unordered_map partials; + std::deque partials; std::unordered_map subscriptions; std::unordered_map audioKeyCallbacks; @@ -129,9 +134,10 @@ class MercurySession : public bell::Task, public cspot::Session { std::atomic isRunning = false; std::atomic isReconnecting = false; std::atomic executeEstabilishedCallback = false; + std::atomic connection_lost = false; void failAllPending(); - std::pair decodeResponse(const std::vector& data); + MercurySession::Response decodeResponse(const std::vector& data); }; } // namespace cspot diff --git a/cspot/include/PlaybackState.h b/cspot/include/PlaybackState.h deleted file mode 100644 index a79eab01..00000000 --- a/cspot/include/PlaybackState.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include // for uint8_t, uint32_t -#include // for shared_ptr -#include // for string -#include // for vector - -#include "TrackReference.h" -#include "protobuf/spirc.pb.h" // for Frame, TrackRef, CapabilityType, Mess... - -namespace cspot { -struct Context; - -class PlaybackState { - private: - std::shared_ptr ctx; - - uint32_t seqNum = 0; - uint8_t capabilityIndex = 0; - - std::vector frameData; - - void addCapability( - CapabilityType typ, int intValue = -1, - std::vector stringsValue = std::vector()); - - public: - Frame innerFrame; - Frame remoteFrame; - - std::vector remoteTracks; - - enum class State { Playing, Stopped, Loading, Paused }; - - /** - * @brief Player state represents the current state of player. - * - * Responsible for keeping track of player's state. Doesn't control the playback itself. - * - * @param timeProvider synced time provider - */ - PlaybackState(std::shared_ptr ctx); - - ~PlaybackState(); - - /** - * @brief Updates state according to current playback state. - * - * @param state playback state - */ - void setPlaybackState(const PlaybackState::State state); - - /** - * @brief Sets player activity - * - * @param isActive activity status - */ - void setActive(bool isActive); - - /** - * @brief Simple getter - * - * @return true player is active - * @return false player is inactive - */ - bool isActive(); - - /** - * @brief Updates local track position. - * - * @param position position in milliseconds - */ - void updatePositionMs(uint32_t position); - - /** - * @brief Sets local volume on internal state. - * - * @param volume volume between 0 and UINT16 max - */ - void setVolume(uint32_t volume); - - /** - * @brief Updates local track queue from remote data. - */ - void syncWithRemote(); - - /** - * @brief Encodes current frame into binary data via protobuf. - * - * @param typ message type to include in frame type - * @return std::vector binary frame data - */ - std::vector encodeCurrentFrame(MessageType typ); - - bool decodeRemoteFrame(std::vector& data); -}; -} // namespace cspot diff --git a/cspot/include/PlayerContext.h b/cspot/include/PlayerContext.h new file mode 100644 index 00000000..59019c8c --- /dev/null +++ b/cspot/include/PlayerContext.h @@ -0,0 +1,64 @@ +#ifndef PLAYER_CONTEXT_H +#define PLAYER_CONTEXT_H + +#include +#include // for shared_ptr +#include //for scoped_loc, mutex... +#include +#include //for random_device and default_random_engine +#include // for pair +#include //for vector + +#include "BellTask.h" +#include "CSpotContext.h" +#include "TrackReference.h" //for TrackReference +#include "nlohmann/json.hpp" // for basic_json<>::object_t, basic_json +#include "nlohmann/json_fwd.hpp" // for json + +#include "protobuf/metadata.pb.h" // for Track, _Track, AudioFile, Episode +#define MAX_TRACKS 80 +namespace cspot { +struct PlayerContext { + PlayerContext(std::shared_ptr ctx, PlayerState* playerState, + std::vector* tracks, uint8_t* index) { + this->ctx = ctx; + this->playerState = playerState; + this->tracks = tracks; + this->index = index; + } + void resolveRadio( + std::vector> metadata_map, + void (*responseFunction)(void*), bool secondTry = false); + + void resolveTracklist( + std::vector> metadata_map, + void (*responseFunction)(void*), bool state_changed = false); + uint8_t jsonToTracklist( + std::vector* tracks, + std::vector> metadata_map, + nlohmann::json::value_type& json_tracks, const char* provider, + int64_t offset = 0, uint8_t page = 0, bool shuffle = false, + bool preloadedTrack = false); + void createIndexBasedOnTracklist(std::vector* tracks, + nlohmann::json::value_type& json_tracks, + bool shuffle, uint8_t page); + //void jsonToPlayerStateContext(PlayerState* playerState, std::vector* tracks, uint8_t* index, std::vector> metadata_map,nlohmann::json::object_t context); + static char* createStringReferenceIfFound( + nlohmann::json::value_type& jsonObject, const char* key); + uint64_t radio_offset = 0; + std::mutex trackListMutex; + std::shared_ptr ctx; + PlayerState* playerState; + std::vector* tracks; + uint8_t* index; + std::vector alternative_index; + char* next_page_url = NULL; + std::string context_uri; + ~PlayerContext() { + if (next_page_url != NULL) + free(next_page_url); + } +}; +}; // namespace cspot + +#endif \ No newline at end of file diff --git a/cspot/include/SpircHandler.h b/cspot/include/SpircHandler.h deleted file mode 100644 index 7d558cd8..00000000 --- a/cspot/include/SpircHandler.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include // for uint32_t, uint8_t -#include // for function -#include // for shared_ptr, unique_ptr -#include // for string -#include // for variant -#include // for vector - -#include "CDNAudioFile.h" // for CDNTrackStream, CDNTrackStream::Track... -#include "TrackQueue.h" -#include "protobuf/spirc.pb.h" // for MessageType - -namespace cspot { -class TrackPlayer; -struct Context; - -class SpircHandler { - public: - SpircHandler(std::shared_ptr ctx); - - enum class EventType { - PLAY_PAUSE, - VOLUME, - TRACK_INFO, - DISC, - NEXT, - PREV, - SEEK, - DEPLETED, - FLUSH, - PLAYBACK_START - }; - - typedef std::variant EventData; - - struct Event { - EventType eventType; - EventData data; - }; - - typedef std::function)> EventHandler; - - void subscribeToMercury(); - std::shared_ptr getTrackPlayer(); - - void setEventHandler(EventHandler handler); - - void setPause(bool pause); - - bool previousSong(); - - bool nextSong(); - - void notifyAudioReachedPlayback(); - void notifyAudioEnded(); - void updatePositionMs(uint32_t position); - void setRemoteVolume(int volume); - void loadTrackFromURI(const std::string& uri); - std::shared_ptr getTrackQueue() { return trackQueue; } - - void disconnect(); - - private: - std::shared_ptr ctx; - std::shared_ptr trackPlayer; - std::shared_ptr trackQueue; - - EventHandler eventHandler = nullptr; - - std::shared_ptr playbackState; - - void sendCmd(MessageType typ); - - void sendEvent(EventType type); - void sendEvent(EventType type, EventData data); - - bool skipSong(TrackQueue::SkipDirection dir); - void handleFrame(std::vector& data); - void notify(); -}; -} // namespace cspot diff --git a/cspot/include/TrackPlayer.h b/cspot/include/TrackPlayer.h index 1577c476..aa738ce9 100644 --- a/cspot/include/TrackPlayer.h +++ b/cspot/include/TrackPlayer.h @@ -17,11 +17,13 @@ namespace bell { class WrappedSemaphore; } // namespace bell +#ifndef CONFIG_BELL_NOCODEC #ifdef BELL_VORBIS_FLOAT #include "vorbis/vorbisfile.h" #else #include "ivorbisfile.h" // for OggVorbis_File, ov_callbacks #endif +#endif namespace cspot { class TrackProvider; @@ -34,9 +36,17 @@ class TrackPlayer : bell::Task { // Callback types typedef std::function, bool)> TrackLoadedCallback; - typedef std::function + typedef std::function DataCallback; - typedef std::function EOFCallback; + typedef std::function EOFCallback; + typedef std::function SeekableCallback; + EOFCallback eofCallback; TrackPlayer(std::shared_ptr ctx, std::shared_ptr trackQueue, @@ -45,17 +55,21 @@ class TrackPlayer : bell::Task { void loadTrackFromRef(TrackReference& ref, size_t playbackMs, bool startAutomatically); - void setDataCallback(DataCallback callback); + void setDataCallback(DataCallback callback, + SeekableCallback seekable_callback = nullptr, + SeekableCallback spaces_available = nullptr); // CDNTrackStream::TrackInfo getCurrentTrackInfo(); void seekMs(size_t ms); void resetState(bool paused = false); +#ifndef CONFIG_BELL_NOCODEC // Vorbis codec callbacks size_t _vorbisRead(void* ptr, size_t size, size_t nmemb); size_t _vorbisClose(); int _vorbisSeek(int64_t offset, int whence); long _vorbisTell(); +#endif void stop(); void start(); @@ -69,19 +83,29 @@ class TrackPlayer : bell::Task { TrackLoadedCallback trackLoaded; DataCallback dataCallback = nullptr; - EOFCallback eofCallback; +#ifdef CONFIG_BELL_NOCODEC + SeekableCallback spaces_available = nullptr; + SeekableCallback seekable_callback; + size_t seekable_offset; +#endif // Playback control std::atomic currentSongPlaying; std::mutex playbackMutex; std::mutex dataOutMutex; +#ifndef CONFIG_BELL_NOCODEC // Vorbis related OggVorbis_File vorbisFile; ov_callbacks vorbisCallbacks; int currentSection; +#endif +#ifndef CONFIG_BELL_NOCODEC std::vector pcmBuffer = std::vector(1024); +#else + std::vector pcmBuffer = std::vector(128); +#endif bool autoStart = false; diff --git a/cspot/include/TrackQueue.h b/cspot/include/TrackQueue.h index 8e2f0c37..513026ba 100644 --- a/cspot/include/TrackQueue.h +++ b/cspot/include/TrackQueue.h @@ -5,11 +5,14 @@ #include #include #include +#include // for pair #include "BellTask.h" -#include "PlaybackState.h" +#include "EventManager.h" // for TrackMetrics #include "TrackReference.h" +#include "Utils.h" +#include "protobuf/connect.pb.h" // for ProvidedTrack #include "protobuf/metadata.pb.h" // for Track, _Track, AudioFile, Episode namespace bell { @@ -32,8 +35,8 @@ struct TrackInfo { class QueuedTrack { public: - QueuedTrack(TrackReference& ref, std::shared_ptr ctx, - uint32_t requestedPosition = 0); + QueuedTrack(ProvidedTrack& ref, std::shared_ptr ctx, + int64_t requestedPosition = 0); ~QueuedTrack(); enum class State { @@ -49,13 +52,21 @@ class QueuedTrack { std::shared_ptr loadedSemaphore; State state = State::QUEUED; // Current state of the track - TrackReference ref; // Holds GID, URI and Context TrackInfo trackInfo; // Full track information fetched from spotify, name etc - - uint32_t requestedPosition; + ProvidedTrack ref; std::string identifier; + uint32_t playingTrackIndex; + uint32_t requestedPosition; bool loading = false; + // PB data + Track pbTrack = Track_init_zero; + Episode pbEpisode = Episode_init_zero; + + // EventManager data + int64_t written_bytes = 0; + std::shared_ptr trackMetrics; + // Will return nullptr if the track is not ready std::shared_ptr getAudioFile(); @@ -82,53 +93,41 @@ class QueuedTrack { std::vector trackId, fileId, audioKey; std::string cdnUrl; + std::pair> gid = { + SpotifyFileType::UNKNOWN, + {}}; }; class TrackQueue : public bell::Task { public: - TrackQueue(std::shared_ptr ctx, - std::shared_ptr playbackState); + TrackQueue(std::shared_ptr ctx); ~TrackQueue(); enum class SkipDirection { NEXT, PREV }; std::shared_ptr playableSemaphore; + std::shared_ptr accessKeyFetcher; std::atomic notifyPending = false; + std::deque> preloadedTracks; + bool repeat = false; void runTask() override; void stopTask(); - bool hasTracks(); - bool isFinished(); - bool skipTrack(SkipDirection dir, bool expectNotify = true); - bool updateTracks(uint32_t requestedPosition = 0, bool initial = false); + bool skipTrack(SkipDirection dir, bool expectNotify = false); TrackInfo getTrackInfo(std::string_view identifier); std::shared_ptr consumeTrack( std::shared_ptr prevSong, int& offset); + std::mutex tracksMutex, runningMutex; private: - static const int MAX_TRACKS_PRELOAD = 3; - - std::shared_ptr accessKeyFetcher; - std::shared_ptr playbackState; std::shared_ptr ctx; std::shared_ptr processSemaphore; - std::deque> preloadedTracks; - std::vector currentTracks; - std::mutex tracksMutex, runningMutex; - - // PB data - Track pbTrack; - Episode pbEpisode; + bool isRunning = false; std::string accessKey; - int16_t currentTracksIndex = -1; - - bool isRunning = false; - void processTrack(std::shared_ptr track); - bool queueNextTrack(int offset = 0, uint32_t positionMs = 0); }; -} // namespace cspot +} // namespace cspot \ No newline at end of file diff --git a/cspot/include/TrackReference.h b/cspot/include/TrackReference.h index 8b986349..70b04e0a 100644 --- a/cspot/include/TrackReference.h +++ b/cspot/include/TrackReference.h @@ -5,12 +5,28 @@ #include #include #include "NanoPBHelper.h" +#include "Utils.h" //for base62decode #include "pb_decode.h" -#include "protobuf/spirc.pb.h" +#include "protobuf/connect.pb.h" + +#define TRACK_SEND_LIMIT 25 namespace cspot { struct TrackReference { TrackReference(); + TrackReference(std::string uri, std::string context) : type(Type::TRACK) { + this->gid = base62Decode(uri).second; + //this->uri=uri; + this->context = context; + } + TrackReference(std::string uri) : type(Type::TRACK) { + gid = base62Decode(uri).second; + + if (uri.find("episode:") != std::string::npos) { + type = Type::EPISODE; + } + this->uri = uri; + } // Resolved track GID std::vector gid; @@ -27,10 +43,22 @@ struct TrackReference { bool operator==(const TrackReference& other) const; // Encodes list of track references into a pb structure, used by nanopb - static bool pbEncodeTrackList(pb_ostream_t* stream, const pb_field_t* field, - void* const* arg); + static bool pbEncodeProvidedTracks(pb_ostream_t* stream, + const pb_field_t* field, void* const* arg); + + static bool pbDecodeProvidedTracks(pb_istream_t* stream, + const pb_field_t* field, void** arg); + + static void clearProvidedTracklist(std::vector* tracklist) { + for (auto& track : *tracklist) + pbReleaseProvidedTrack(&track); + tracklist->clear(); + } - static bool pbDecodeTrackList(pb_istream_t* stream, const pb_field_t* field, - void** arg); + static void pbReleaseProvidedTrack(ProvidedTrack* track) { + if (track->metadata_count < track->full_metadata_count) + track->metadata_count = track->full_metadata_count; + pb_release(ProvidedTrack_fields, track); + } }; } // namespace cspot diff --git a/cspot/include/Utils.h b/cspot/include/Utils.h index a52be4ea..e2ce70ca 100644 --- a/cspot/include/Utils.h +++ b/cspot/include/Utils.h @@ -15,8 +15,10 @@ #include // for unique_ptr #include // for runtime_error #include // for string +#include // for pair #define HMAC_SHA1_BLOCKSIZE 64 +enum class SpotifyFileType { TRACK, EPISODE, UNKNOWN }; /** * @brief Returns current timestamp @@ -33,6 +35,14 @@ unsigned long long getCurrentTimestamp(); */ uint64_t hton64(uint64_t value); +/** + * @brief Encodes a bytestream to a base64 string + * + * @param v std::vector + * @return std::string + */ +std::string base64Encode(const std::vector& v); + std::vector bigNumDivide(std::vector num, int n); /** @@ -55,6 +65,14 @@ std::vector bigNumAdd(std::vector num, int n); unsigned char h2int(char c); +/** + * @brief Extracts the spotify id from a spotify uri and decodes its base62-format + * + * @param uri spotify uri/spotify id(base62) string + * @return std::vector gid + */ +std::pair> base62Decode(std::string uri); + std::string urlDecode(std::string str); /** diff --git a/cspot/protobuf/connect.options b/cspot/protobuf/connect.options new file mode 100644 index 00000000..63c63f89 --- /dev/null +++ b/cspot/protobuf/connect.options @@ -0,0 +1,79 @@ +DeviceInfo.name type:FT_POINTER +DeviceInfo.device_id type:FT_POINTER +DeviceInfo.client_id type:FT_POINTER +DeviceInfo.spirc_version type:FT_POINTER +//DeviceInfo.supported_types type:FT_POINTER +DeviceInfo.device_software_version type:FT_POINTER +DeviceInfo.capabilities max_count:27, fixed_count:false +DeviceInfo.model type:FT_POINTER +DeviceInfo.brand type:FT_POINTER +PutStateRequest.callback_url type:FT_POINTER +PutStateRequest.last_command_sent_by_device_id type:FT_POINTER +Capabilities.stringValue max_count:50, max_size: 50 +Capabilities.intValue max_count:50 +Capabilities.supported_types type:FT_POINTER +Capabilities.Supported_typesEntry type:FT_POINTER +Cluster.device max_count:10 fixed_count:false +Cluster.DeviceEntry.key type:FT_POINTER +Cluster.active_device_id type:FT_POINTER +ProvidedTrack.uri type:FT_POINTER +ProvidedTrack.uid type:FT_POINTER +ProvidedTrack.metadata max_count:30, fixed_count:false +ProvidedTrack.MetadataEntry type:FT_POINTER +ProvidedTrack.removed type:FT_POINTER +ProvidedTrack.blocked type:FT_POINTER +ProvidedTrack.provider type:FT_POINTER +ProvidedTrack.album_uri type:FT_POINTER +ProvidedTrack.disallow_reasons type:FT_POINTER +ProvidedTrack.artist_uri type:FT_POINTER +ProvidedTrack.disallow_undecided type:FT_POINTER +PlayOrigin.feature_identifier type:FT_POINTER +PlayOrigin.feature_version type:FT_POINTER +PlayOrigin.view_uri type:FT_POINTER +PlayOrigin.external_referrer type:FT_POINTER +PlayOrigin.referrer_identifier type:FT_POINTER +PlayOrigin.device_identifier type:FT_POINTER +PlayOrigin.feature_classes type:FT_POINTER +PlayerState.playback_id type:FT_POINTER + +ContextPlayerOptions.context_enhancement max_count:2, fixed_count:false +ContextPlayerOptions.ContextEnhancementEntry type:FT_POINTER + +Restrictions type:FT_POINTER + +PlayerState.context_uri type:FT_POINTER +PlayerState.context_url type:FT_POINTER +PlayerState.context_metadata type:FT_POINTER +PlayerState.ContextMetadataEntry type:FT_POINTER +PlayerState.page_metadata type:FT_POINTER +PlayerState.PageMetadataEntry type:FT_POINTER +PlayerState.session_id type:FT_POINTER +PlayerState.queue_revision type:FT_POINTER +PlayerState.entity_uri type:FT_POINTER +PlayerState.playback_provider type:FT_POINTER +PlayerState.random_message type:FT_POINTER + +Restrictions.disallow_pausing_reasons type:FT_POINTER +Restrictions.disallow_resuming_reasons type:FT_POINTER +Restrictions.disallow_seeking_reasons type:FT_POINTER +Restrictions.disallow_peeking_prev_reasons type:FT_POINTER +Restrictions.disallow_peeking_next_reasons type:FT_POINTER +Restrictions.disallow_skipping_prev_reasons type:FT_POINTER +Restrictions.disallow_skipping_next_reasons type:FT_POINTER +Restrictions.disallow_toggling_repeat_context_reasons type:FT_POINTER +Restrictions.disallow_toggling_repeat_track_reasons type:FT_POINTER +Restrictions.disallow_toggling_shuffle_reasons type:FT_POINTER +Restrictions.disallow_set_queue_reasons type:FT_POINTER +Restrictions.disallow_interrupting_playback_reasons type:FT_POINTER +Restrictions.disallow_transferring_playback_reasons type:FT_POINTER +Restrictions.disallow_remote_control_reasons type:FT_POINTER +Restrictions.disallow_inserting_into_next_tracks_reasons type:FT_POINTER +Restrictions.disallow_inserting_into_context_tracks_reasons type:FT_POINTER +Restrictions.disallow_reordering_in_next_tracks_reasons type:FT_POINTER +Restrictions.disallow_reordering_in_context_tracks_reasons type:FT_POINTER +Restrictions.disallow_removing_from_next_tracks_reasons type:FT_POINTER +Restrictions.disallow_removing_from_context_tracks_reasons type:FT_POINTER +Restrictions.disallow_updating_context_reasons type:FT_POINTER +Restrictions.disallow_playing_reasons type:FT_POINTER +Restrictions.disallow_stopping_reasons type:FT_POINTER +Restrictions.disallow_loading_context_reasons type:FT_POINTER \ No newline at end of file diff --git a/cspot/protobuf/connect.proto b/cspot/protobuf/connect.proto new file mode 100644 index 00000000..c27b843f --- /dev/null +++ b/cspot/protobuf/connect.proto @@ -0,0 +1,345 @@ +syntax = "proto2"; + +message PlayerState { + optional int64 timestamp = 1; + optional string context_uri = 2; + optional string context_url = 3; + optional Restrictions context_restrictions = 4; + optional PlayOrigin play_origin = 5; + optional ContextIndex index = 6; + optional ProvidedTrack track = 7; + optional string playback_id = 8; + optional double playback_speed = 9; + optional int64 position_as_of_timestamp = 10; + optional int64 duration = 11; + optional bool is_playing = 12; + optional bool is_paused = 13; + optional bool is_buffering = 14; + optional bool is_system_initiated = 15; + optional ContextPlayerOptions options = 16; + optional Restrictions restrictions = 17; + optional Suppressions suppressions = 18; + repeated ProvidedTrack prev_tracks = 19; + repeated ProvidedTrack next_tracks = 20; + map context_metadata = 21; + map page_metadata = 22; + optional string session_id = 23; + optional string queue_revision = 24; + optional int64 position = 25; + optional string entity_uri = 26; + repeated ProvidedTrack reverse = 27; + repeated ProvidedTrack future = 28; + optional PlaybackQuality playback_quality = 32; + optional string playback_provider = 33; + optional string random_message = 35; +} + +message ProvidedTrack { + optional string uri = 1; + optional string uid = 2; + map metadata = 3; + optional string removed = 4; + repeated string blocked = 5; + optional string provider = 6; + optional Restrictions restrictions = 7; + optional string album_uri = 8; + repeated string disallow_reasons = 9; + optional string artist_uri = 10; + repeated string disallow_undecided = 11; + optional uint32 page = 253; + optional uint32 original_index = 254; + optional uint32 full_metadata_count = 255; +} + +message ContextIndex { + optional uint32 page = 1; + optional uint32 track = 2; +} + +message Restrictions { + repeated string disallow_pausing_reasons = 1; + repeated string disallow_resuming_reasons = 2; + repeated string disallow_seeking_reasons = 3; + repeated string disallow_peeking_prev_reasons = 4; + repeated string disallow_peeking_next_reasons = 5; + repeated string disallow_skipping_prev_reasons = 6; + repeated string disallow_skipping_next_reasons = 7; + repeated string disallow_toggling_repeat_context_reasons = 8; + repeated string disallow_toggling_repeat_track_reasons = 9; + repeated string disallow_toggling_shuffle_reasons = 10; + repeated string disallow_set_queue_reasons = 11; + repeated string disallow_interrupting_playback_reasons = 12; + repeated string disallow_transferring_playback_reasons = 13; + repeated string disallow_remote_control_reasons = 14; + repeated string disallow_inserting_into_next_tracks_reasons = 15; + repeated string disallow_inserting_into_context_tracks_reasons = 16; + repeated string disallow_reordering_in_next_tracks_reasons = 17; + repeated string disallow_reordering_in_context_tracks_reasons = 18; + repeated string disallow_removing_from_next_tracks_reasons = 19; + repeated string disallow_removing_from_context_tracks_reasons = 20; + repeated string disallow_updating_context_reasons = 21; + repeated string disallow_playing_reasons = 22; + repeated string disallow_stopping_reasons = 23; + repeated string disallow_loading_context_reasons = 25; +} + +message PlayOrigin { + optional string feature_identifier = 1; + optional string feature_version = 2; + optional string view_uri = 3; + optional string external_referrer = 4; + optional string referrer_identifier = 5; + optional string device_identifier = 6; + optional string feature_classes = 7; +} + +message ContextEnhancement{ + optional string key = 1; + optional string value = 2; +} + +message ContextPlayerOptions { + optional bool shuffling_context = 1; + optional bool repeating_context = 2; + optional bool repeating_track = 3; + + map context_enhancement = 5; +} + +message Suppressions { + repeated string providers = 1; +} + +enum BitrateLevel { + unknown = 0; + low = 1; + normal = 2; + high = 3; + veryhigh = 4; + normalized = 5; +} + +enum BitrateStrategy { + unknown_strategy = 0; + best_matching = 1; + backend_advised = 2; + offlined_file = 3; + cached_file = 4; + local_file = 5; +} + +enum HiFiStatus { + none = 0; + off = 1; + on = 2; +} + +message PlaybackQuality { + optional BitrateLevel bitrate_level = 1; + optional BitrateStrategy strategy = 2; + optional BitrateLevel target_bitrate_level = 3; + optional bool target_bitrate_available = 4; + optional HiFiStatus hifi_status = 5; +} + +message ClusterUpdate { + optional Cluster cluster = 1; + optional ClusterUpdateReason update_reason = 2; + optional string ack_id = 3; + repeated string devices_that_changed = 4; +} + +message Device { + optional DeviceInfo device_info = 1; + optional PlayerState player_state = 2; + optional PrivateDeviceInfo private_device_info = 3; + optional bytes transfer_data = 4; // TransferState +} + +message Cluster { + optional uint64 timestamp = 1; + optional string active_device_id = 2; + optional PlayerState player_state = 3; + map device = 4; + optional bytes transfer_data = 5; + optional uint64 transfer_data_timestamp = 6; + optional int64 not_playing_since_timestamp = 7; + optional bool need_full_player_state = 8; + optional int64 server_timestamp_ms = 9; +} + +message PutStateRequest { + optional string callback_url = 1; + optional Device device = 2; + optional MemberType member_type = 3; + optional bool is_active = 4; + optional PutStateReason put_state_reason = 5; + optional uint32 message_id = 6; + optional string last_command_sent_by_device_id = 7; + optional uint32 last_command_message_id = 8; + optional uint64 started_playing_at = 9; + optional uint64 has_been_playing_for_ms = 11; + optional uint64 client_side_timestamp = 12; + optional bool only_write_player_state = 13; +} + +message PrivateDeviceInfo { + optional string platform = 1; +} + +message SubscribeRequest { + optional string callback_url = 1; +} + +message DeviceInfo { + message DeviceAliasesEntry { + optional uint32 key = 1; + optional DeviceAlias value = 2; + } + optional bool can_play = 1; + optional uint32 volume = 2; + optional string name = 3; + optional Capabilities capabilities = 4; + optional string device_software_version = 6; + optional DeviceType device_type = 7; + optional string spirc_version = 9; + optional string device_id = 10; + optional bool is_private_session = 11; + optional bool is_social_connect = 12; + optional string client_id = 13; + optional string brand = 14; + optional string model = 15; + map metadata_map = 16; + optional string product_id = 17; + optional string deduplication_id = 18; + optional uint32 selected_alias_id = 19; + repeated DeviceAliasesEntry device_aliases = 20; + optional bool is_offline = 21; + optional string public_ip = 22; + optional string license = 23; +} + +message DeviceAlias { + optional uint32 id = 1; + optional string name = 2; + optional bool is_group = 3; +} + +message Capabilities { + optional bool can_be_player = 2; + optional bool restrict_to_local = 3; + optional bool gaia_eq_connect_id = 5; + optional bool supports_logout = 6; + optional bool is_observable = 7; + optional int32 volume_steps = 8; + repeated string supported_types = 9; + optional bool command_acks = 10; + optional bool supports_rename = 11; + optional bool hidden = 12; + optional bool disable_volume = 13; + optional bool connect_disabled = 14; + optional bool supports_playlist_v2 = 15; + optional bool is_controllable = 16; + optional bool supports_external_episodes = 17; + optional bool supports_set_backend_metadata = 18; + optional bool supports_transfer_command = 19; + optional bool supports_command_request = 20; + optional bool is_voice_enabled = 21; + optional bool needs_full_player_state = 22; + optional bool supports_gzip_pushes = 23; + optional bool supports_lossless_audio = 24; + optional bool supports_set_options_command = 25; + optional CapabilitySupportDetails supports_hifi = 26; + // reserved 1, "supported_contexts"; +} + +message CapabilitySupportDetails { + optional bool fully_supported = 1; + optional bool user_eligible = 2; + optional bool device_supported = 3; +} + +message ConnectCommandOptions { + optional int32 message_id = 1; +} + +message LogoutCommand { + optional ConnectCommandOptions command_options = 1; +} + +message SetVolumeCommand { + optional int32 volume = 1; + optional ConnectCommandOptions command_options = 2; +} + +message RenameCommand { + optional string rename_to = 1; + optional ConnectCommandOptions command_options = 2; +} + +message SetBackendMetadataCommand { + map metadata = 1; +} + +enum SendCommandResult { + UNKNOWN_SEND_COMMAND_RESULT = 0; + SUCCESS = 1; + DEVICE_NOT_FOUND = 2; + CONTEXT_PLAYER_ERROR = 3; + DEVICE_DISAPPEARED = 4; + UPSTREAM_ERROR = 5; + DEVICE_DOES_NOT_SUPPORT_COMMAND = 6; + RATE_LIMITED = 7; +} + +enum PutStateReason { + UNKNOWN_PUT_STATE_REASON = 0; + SPIRC_HELLO = 1; + SPIRC_NOTIFY = 2; + NEW_DEVICE = 3; + PLAYER_STATE_CHANGED = 4; + VOLUME_CHANGED = 5; + PICKER_OPENED = 6; + BECAME_INACTIVE = 7; + ALIAS_CHANGED = 8; +} + +enum MemberType { + SPIRC_V2 = 0; + SPIRC_V3 = 1; + CONNECT_STATE = 2; + CONNECT_STATE_EXTENDED = 5; + ACTIVE_DEVICE_TRACKER = 6; + PLAY_TOKEN = 7; +} + +enum ClusterUpdateReason { + UNKNOWN_CLUSTER_UPDATE_REASON = 0; + DEVICES_DISAPPEARED = 1; + DEVICE_STATE_CHANGED = 2; + NEW_DEVICE_APPEARED = 3; + DEVICE_VOLUME_CHANGED = 4; + DEVICE_ALIAS_CHANGED = 5; +} + +enum DeviceType { + UNKNOWN = 0; + COMPUTER = 1; + TABLET = 2; + SMARTPHONE = 3; + SPEAKER = 4; + TV = 5; + AVR = 6; + STB = 7; + AUDIO_DONGLE = 8; + GAME_CONSOLE = 9; + CAST_VIDEO = 10; + CAST_AUDIO = 11; + AUTOMOBILE = 12; + SMARTWATCH = 13; + CHROMEBOOK = 14; + UNKNOWN_SPOTIFY = 100; + CAR_THING = 101; + OBSERVER = 102; + HOME_THING = 103; +} diff --git a/cspot/protobuf/mercury.options b/cspot/protobuf/mercury.options index d0fb231b..071a17b9 100644 --- a/cspot/protobuf/mercury.options +++ b/cspot/protobuf/mercury.options @@ -1,5 +1,5 @@ -Header.uri max_size:256, fixed_length:false -Header.method max_size:64, fixed_length:false +Header.uri type:FT_POINTER +Header.method type:FT_POINTER UserField.key type:FT_POINTER UserField.value type:FT_POINTER -Header.user_fields max_count:64, fixed_count:false \ No newline at end of file +Header.user_fields max_count:10, fixed_count:false \ No newline at end of file diff --git a/cspot/protobuf/spirc.options b/cspot/protobuf/spirc.options index b7331f53..1804712a 100644 --- a/cspot/protobuf/spirc.options +++ b/cspot/protobuf/spirc.options @@ -7,4 +7,6 @@ DeviceState.sw_version type:FT_POINTER DeviceState.name type:FT_POINTER DeviceState.capabilities max_count:17, fixed_count:false State.context_uri type:FT_POINTER +State.last_command_ident type:FT_POINTER +State.context_description type:FT_POINTER TrackRef.queued type:FT_CALLBACK \ No newline at end of file diff --git a/cspot/protobuf/spirc.proto b/cspot/protobuf/spirc.proto index 5d54bd26..fcd3a512 100644 --- a/cspot/protobuf/spirc.proto +++ b/cspot/protobuf/spirc.proto @@ -43,6 +43,8 @@ message State { optional string context_description = 0x8; optional bool shuffle = 0xd; optional bool repeat = 0xe; + optional string last_command_ident = 0x14; + optional uint32 last_command_msgid = 0x15; optional uint32 playing_track_index = 0x1a; repeated TrackRef track = 0x1b; } diff --git a/cspot/src/DeviceStateHandler.cpp b/cspot/src/DeviceStateHandler.cpp new file mode 100644 index 00000000..e6c1cfa7 --- /dev/null +++ b/cspot/src/DeviceStateHandler.cpp @@ -0,0 +1,1169 @@ +#include "DeviceStateHandler.h" + +#include // for strdup, memcpy, strcpy, strlen +#include // for uint8_t +#include // for unreference, NULL, realloc, rand +#include +#include // for shared_ptr +#include // for remove_extent_t +#include // for swap + +#include "BellLogger.h" // for AbstractLogger +#include "BellUtils.h" // for BELL_SLEEP_MS +#include "CSpotContext.h" // for Context::ConfigState, Context (ptr o... +#include "ConstantParameters.h" // for protocolVersion, swVersion +#include "Logger.h" // for CSPOT_LOG +#include "NanoPBHelper.h" // for pbEncode, pbPutString +#include "Packet.h" // for cspot +#include "TrackReference.h" // for cspot +#include "nlohmann/json.hpp" // for basic_json<>::object_t, basic_json +#include "nlohmann/json_fwd.hpp" // for json +#include "pb.h" // for pb_bytes_array_t, PB_BYTES_ARRAY_T_A... +#include "pb_decode.h" // for pb_release + +using namespace cspot; + +static DeviceStateHandler* handler; + +void DeviceStateHandler::reloadTrackList(void*) { + if (strcmp(handler->currentTracks[handler->offset - 1].uri, + "spotify:delimiter") == 0 && + handler->device.player_state.is_playing) { + handler->ctx->playbackMetrics->end_reason = cspot::PlaybackMetrics::REMOTE; + handler->ctx->playbackMetrics->end_source = "unknown"; + handler->trackPlayer->stop(); + handler->device.player_state.has_is_playing = true; + handler->device.player_state.is_playing = false; + handler->device.player_state.track = ProvidedTrack_init_zero; + handler->device.player_state.has_track = false; + if (handler->device.player_state.has_restrictions) + pb_release(Restrictions_fields, + &handler->device.player_state.restrictions); + handler->device.player_state.restrictions = Restrictions_init_zero; + handler->device.player_state.has_restrictions = false; + handler->putPlayerState(); + handler->sendCommand(CommandType::DISC); + return; + } + if (!handler->trackQueue->preloadedTracks.size()) { + handler->trackQueue->preloadedTracks.push_back( + std::make_shared( + handler->currentTracks[handler->offset - 1], handler->ctx, + handler->offsetFromStartInMillis)); + handler->offsetFromStartInMillis = 0; + } + if (handler->currentTracks.size() > + handler->trackQueue->preloadedTracks.size() + handler->offset) { + while (handler->currentTracks.size() > + handler->trackQueue->preloadedTracks.size() + handler->offset && + handler->trackQueue->preloadedTracks.size() < 3) { + handler->trackQueue->preloadedTracks.push_back( + std::make_shared( + handler + ->currentTracks[handler->offset + + handler->trackQueue->preloadedTracks.size() - + 1], + handler->ctx, 0)); + } + } + if (handler->reloadPreloadedTracks) { + handler->needsToBeSkipped = true; + handler->trackPlayer->start(); + handler->trackPlayer->resetState(); + handler->reloadPreloadedTracks = false; + handler->sendCommand(CommandType::PLAYBACK_START); + } + if (handler->playerStateChanged) { + handler->putPlayerState( + PutStateReason::PutStateReason_PLAYER_STATE_CHANGED); + handler->playerStateChanged = false; + } +} +DeviceStateHandler::DeviceStateHandler(std::shared_ptr ctx) { + handler = this; + this->ctx = ctx; + this->trackQueue = std::make_shared(ctx); + this->playerContext = std::make_shared( + ctx, &this->device.player_state, ¤tTracks, &offset); + + auto EOFCallback = [this](bool loaded) { + CSPOT_LOG(debug, "Ended track, needs_to_be_skipped = %s", + needsToBeSkipped ? "true" : "false"); + if (needsToBeSkipped) { + if (this->device.player_state.options.repeating_track) + this->trackQueue->preloadedTracks[0]->requestedPosition = 0; + else if (this->trackQueue->preloadedTracks.size()) + skip(CommandType::SKIP_NEXT, true); + } + this->device.player_state.timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + needsToBeSkipped = true; + if (!this->trackQueue->preloadedTracks.size()) + sendCommand(CommandType::DEPLETED); + }; + + auto playerStateChangedCallback = [this](std::shared_ptr track, + bool new_track = false) { + CSPOT_LOG(debug, "Track loaded, new_track = %s", + new_track ? "true" : "false"); + if (new_track) { + this->device.player_state.timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + //putPlayerState(); + sendCommand(CommandType::PLAYBACK, trackQueue->preloadedTracks[0]); + } else + putPlayerState(); + }; + + this->trackPlayer = std::make_shared( + ctx, trackQueue, EOFCallback, playerStateChangedCallback); + CSPOT_LOG(info, "Started player"); + + auto connectStateSubscription = [this](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return; + if (strstr(res.mercuryHeader.uri, "player/command")) { + if (res.parts[0].size()) + parseCommand(res.parts[0]); + } else if (strstr(res.mercuryHeader.uri, "volume")) { + if (res.parts[0].size()) { + SetVolumeCommand newVolume; + pbDecode(newVolume, SetVolumeCommand_fields, res.parts[0]); + device.device_info.volume = newVolume.volume; + device.device_info.has_volume = true; + sendCommand(CommandType::VOLUME, newVolume.volume); + pb_release(SetVolumeCommand_fields, &newVolume); + } + } else if (strstr(res.mercuryHeader.uri, "cluster")) { + } else + CSPOT_LOG(debug, "Unknown connect_state, uri : %s", + res.mercuryHeader.uri); + }; + + this->ctx->session->addSubscriptionListener("hm://connect-state/", + connectStateSubscription); + CSPOT_LOG(info, "Added connect-state subscription"); + + // the device connection status gets reported trough "hm://social-connect",if active + auto socialConnectSubscription = [this](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return; + if (res.parts[0].size()) { + auto jsonResult = nlohmann::json::parse(res.parts[0]); + if (jsonResult.find("deviceBroadcastStatus") != jsonResult.end()) { + if (jsonResult.find("deviceBroadcastStatus")->find("device_id") != + jsonResult.find("deviceBroadcastStatus")->end()) { + if (jsonResult.find("deviceBroadcastStatus") + ->at("device_id") + .get() != this->ctx->config.deviceId) + goto changePlayerState; + } + } else if (jsonResult.find("reason") != jsonResult.end() && + jsonResult.at("reason") == "SESSION_DELETED") + goto changePlayerState; + return; + changePlayerState: + if (this->is_active) { + this->ctx->playbackMetrics->end_reason = PlaybackMetrics::REMOTE; + this->ctx->playbackMetrics->end_source = "unknown"; + this->trackPlayer->stop(); + this->is_active = false; + if (device.player_state.has_restrictions) + pb_release(Restrictions_fields, &device.player_state.restrictions); + device.player_state.restrictions = Restrictions_init_zero; + device.player_state.has_restrictions = false; + this->putDeviceState(PutStateReason::PutStateReason_BECAME_INACTIVE); + CSPOT_LOG(debug, "Device changed"); + sendCommand(CommandType::DISC); + } + } + }; + + this->ctx->session->addSubscriptionListener("social-connect", + socialConnectSubscription); + CSPOT_LOG(info, "Added social-connect supscription"); + + ctx->session->setConnectedHandler([this]() { + CSPOT_LOG(info, "Registered new device"); + this->putDeviceState(PutStateReason::PutStateReason_NEW_DEVICE); + // Assign country code + this->ctx->config.countryCode = this->ctx->session->getCountryCode(); + }); + + device = {}; + + // Prepare default device state + device.has_device_info = true; + + // Prepare device info + device.device_info.can_play = true; + device.device_info.has_can_play = true; + + device.device_info.has_volume = true; + device.device_info.volume = ctx->config.volume; + + device.device_info.name = strdup(ctx->config.deviceName.c_str()); + + device.device_info.has_capabilities = true; + device.device_info.capabilities = Capabilities{ + true, + 1, //can_be_player + false, + 0, //restrict_to_local + true, + 1, //gaia_eq_connect_id + true, + 0, //supports_logout + true, + 1, //is_observable + true, + 64, //volume_steps + 0, + NULL, //{"audio/track", "audio/episode", "audio/episode+track"}, //supported_types + true, + 1, //command_acks + false, + 0, //supports_rename + false, + 0, //hidden + false, + 0, //disable_volume + false, + 0, //connect_disabled + true, + 1, //supports_playlist_v2 + true, + 1, //is_controllable + true, + 1, //supports_external_episodes + true, + 0, //supports_set_backend_metadata + true, + 1, //supports_transfer_command + false, + 0, //supports_command_request + false, + 0, //is_voice_enabled + true, + 1, //needs_full_player_state + false, + 1, //supports_gzip_pushes + false, + 0, //supports_lossless_audio + true, + 1, //supports_set_options_command + true, {false, 0, false, 0, true, 1}}; + device.device_info.capabilities.supported_types = + (char**)calloc(5, sizeof(char*)); + device.device_info.capabilities.supported_types[0] = strdup("audio/track"); + device.device_info.capabilities.supported_types[1] = strdup("audio/episode"); + device.device_info.capabilities.supported_types[2] = + strdup("audio/episode+track"); + device.device_info.capabilities.supported_types[3] = + strdup("audio/interruption"); + device.device_info.capabilities.supported_types[4] = strdup("audio/local"); + device.device_info.capabilities.supported_types_count = 5; + device.device_info.device_software_version = strdup(swVersion); + device.device_info.has_device_type = true; + device.device_info.device_type = DeviceType::DeviceType_SPEAKER; + device.device_info.spirc_version = strdup(protocolVersion); + device.device_info.device_id = strdup(ctx->config.deviceId.c_str()); + //device.device_info.client_id + device.device_info.brand = strdup(brandName); + device.device_info.model = strdup(informationString); + //device.device_info.metadata_map = {{"debug_level","1"},{"tier1_port","0"},{"device_address_mask",local_ip}}; + //device.device_info.public_ip = ; // gets added trough server + //device.device_info.license = ; +} + +DeviceStateHandler::~DeviceStateHandler() { + TrackReference::clearProvidedTracklist(¤tTracks); + currentTracks.clear(); + pb_release(Device_fields, &device); +} + +void DeviceStateHandler::putDeviceState(PutStateReason put_state_reason) { + std::scoped_lock lock(playerStateMutex); + std::string uri = + "hm://connect-state/v1/devices/" + this->ctx->config.deviceId + "/"; + + std::vector send_tracks = {}; + PutStateRequest tempPutReq = PutStateRequest_init_zero; + tempPutReq.has_device = true; + tempPutReq.has_member_type = true; + tempPutReq.member_type = MemberType::MemberType_CONNECT_STATE; + tempPutReq.has_is_active = true; + tempPutReq.is_active = is_active; + tempPutReq.has_put_state_reason = true; + tempPutReq.put_state_reason = put_state_reason; + tempPutReq.has_message_id = true; + tempPutReq.message_id = last_message_id; + tempPutReq.has_has_been_playing_for_ms = true; + tempPutReq.has_been_playing_for_ms = (uint64_t)-1; + tempPutReq.has_client_side_timestamp = true; + tempPutReq.client_side_timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + tempPutReq.has_only_write_player_state = true; + tempPutReq.only_write_player_state = false; + + if (is_active) { + tempPutReq.has_started_playing_at = true; + tempPutReq.started_playing_at = this->started_playing_at; + tempPutReq.has_been_playing_for_ms = + this->ctx->timeProvider->getSyncedTimestamp() - + this->started_playing_at; + device.has_player_state = true; + device.player_state.has_position_as_of_timestamp = true; + device.player_state.position_as_of_timestamp = + this->ctx->timeProvider->getSyncedTimestamp() - + device.player_state.timestamp; + } else + device.has_player_state = false; + device.player_state.next_tracks.funcs.encode = + &cspot::TrackReference::pbEncodeProvidedTracks; + device.player_state.next_tracks.arg = &queuePacket; + tempPutReq.device = this->device; + + auto putStateRequest = pbEncode(PutStateRequest_fields, &tempPutReq); + tempPutReq.device = Device_init_zero; + pb_release(PutStateRequest_fields, &tempPutReq); + auto parts = MercurySession::DataParts({putStateRequest}); + auto responseLambda = [this](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return; + }; + this->ctx->session->execute(MercurySession::RequestType::PUT, uri, + responseLambda, parts); +} + +void DeviceStateHandler::putPlayerState(PutStateReason put_state_reason) { + std::scoped_lock lock(playerStateMutex); + std::string uri = + "hm://connect-state/v1/devices/" + this->ctx->config.deviceId + "/"; + PutStateRequest tempPutReq = {}; + pb_release(PutStateRequest_fields, &tempPutReq); + tempPutReq = PutStateRequest_init_zero; + tempPutReq.has_device = true; + tempPutReq.has_member_type = false; + tempPutReq.member_type = MemberType::MemberType_CONNECT_STATE; + tempPutReq.has_is_active = true; + tempPutReq.is_active = true; + tempPutReq.has_put_state_reason = true; + tempPutReq.put_state_reason = put_state_reason; + tempPutReq.last_command_message_id = last_message_id; + tempPutReq.has_started_playing_at = true; + tempPutReq.started_playing_at = this->started_playing_at; + tempPutReq.has_has_been_playing_for_ms = true; + tempPutReq.has_been_playing_for_ms = + this->ctx->timeProvider->getSyncedTimestamp() - this->started_playing_at; + tempPutReq.has_client_side_timestamp = true; + tempPutReq.client_side_timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + tempPutReq.has_only_write_player_state = true; + tempPutReq.only_write_player_state = true; + device.player_state.has_position_as_of_timestamp = true; + device.player_state.position_as_of_timestamp = + (int64_t)trackQueue->preloadedTracks[0]->trackMetrics->getPosition(); + device.has_player_state = true; + device.player_state.has_position_as_of_timestamp = true; + device.player_state.position_as_of_timestamp = + trackQueue->preloadedTracks[0]->trackMetrics->getPosition(); + queuePacket = {&offset, ¤tTracks}; + device.player_state.next_tracks.funcs.encode = + &cspot::TrackReference::pbEncodeProvidedTracks; + device.player_state.next_tracks.arg = &queuePacket; + if (device.player_state.track.provider && + strcmp(device.player_state.track.provider, "autoplay") == 0) { + if (device.player_state.has_restrictions) + pb_release(Restrictions_fields, &device.player_state.restrictions); + pb_release(ContextIndex_fields, &device.player_state.index); + device.player_state.index = ContextIndex_init_zero; + device.player_state.has_index = false; + device.player_state.restrictions = Restrictions_init_zero; + if (!device.player_state.is_paused) { + device.player_state.restrictions.disallow_resuming_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions.disallow_resuming_reasons_count = 1; + device.player_state.restrictions.disallow_resuming_reasons[0] = + strdup("not_paused"); + } else { + device.player_state.restrictions.disallow_pausing_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions.disallow_pausing_reasons_count = 1; + device.player_state.restrictions.disallow_pausing_reasons[0] = + strdup("not_playing"); + } + + device.player_state.restrictions.disallow_toggling_repeat_context_reasons = + (char**)calloc(3, sizeof(char*)); + device.player_state.restrictions + .disallow_toggling_repeat_context_reasons_count = 3; + device.player_state.restrictions + .disallow_toggling_repeat_context_reasons[0] = strdup("autoplay"); + device.player_state.restrictions + .disallow_toggling_repeat_context_reasons[1] = + strdup("endless_context"); + device.player_state.restrictions + .disallow_toggling_repeat_context_reasons[2] = strdup("radio"); + + device.player_state.restrictions.disallow_toggling_repeat_track_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions + .disallow_toggling_repeat_track_reasons_count = 1; + device.player_state.restrictions.disallow_toggling_repeat_track_reasons[0] = + strdup("autoplay"); + + device.player_state.restrictions.disallow_toggling_shuffle_reasons = + (char**)calloc(3, sizeof(char*)); + device.player_state.restrictions.disallow_toggling_shuffle_reasons_count = + 3; + device.player_state.restrictions.disallow_toggling_shuffle_reasons[0] = + strdup("autoplay"); + device.player_state.restrictions.disallow_toggling_shuffle_reasons[1] = + strdup("endless_context"); + device.player_state.restrictions.disallow_toggling_shuffle_reasons[2] = + strdup("radio"); + + device.player_state.restrictions.disallow_loading_context_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions.disallow_loading_context_reasons_count = 1; + device.player_state.restrictions.disallow_loading_context_reasons[0] = + strdup("not_supported_by_content_type"); + + device.player_state.has_index = false; + device.player_state.has_restrictions = true; + } else { + device.player_state.index = + ContextIndex{true, device.player_state.track.page, true, + device.player_state.track.original_index}; + if (device.player_state.has_restrictions) + pb_release(Restrictions_fields, &device.player_state.restrictions); + device.player_state.restrictions = Restrictions_init_zero; + if (!device.player_state.is_paused) { + device.player_state.restrictions.disallow_resuming_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions.disallow_resuming_reasons_count = 1; + device.player_state.restrictions.disallow_resuming_reasons[0] = + strdup("not_paused"); + } else { + device.player_state.restrictions.disallow_pausing_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions.disallow_pausing_reasons_count = 1; + device.player_state.restrictions.disallow_pausing_reasons[0] = + strdup("not_playing"); + } + device.player_state.restrictions.disallow_loading_context_reasons = + (char**)calloc(1, sizeof(char*)); + device.player_state.restrictions.disallow_loading_context_reasons_count = 1; + device.player_state.restrictions.disallow_loading_context_reasons[0] = + strdup("not_supported_by_content_type"); + + device.player_state.has_restrictions = true; + } + tempPutReq.device = this->device; + auto putStateRequest = pbEncode(PutStateRequest_fields, &tempPutReq); + tempPutReq.device = Device_init_zero; + pb_release(PutStateRequest_fields, &tempPutReq); + auto parts = MercurySession::DataParts({putStateRequest}); + + auto responseLambda = [this](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return; + }; + this->ctx->session->execute(MercurySession::RequestType::PUT, uri, + responseLambda, parts); +} + +void DeviceStateHandler::disconnect() { + this->trackQueue->stopTask(); + this->trackPlayer->stop(); + this->ctx->session->disconnect(); +} + +void DeviceStateHandler::skip(CommandType dir, bool notify) { + if (dir == CommandType::SKIP_NEXT) { + std::scoped_lock lock(trackQueue->tracksMutex); + this->device.player_state.track = currentTracks[offset]; + if (this->device.player_state.track.full_metadata_count > + this->device.player_state.track.metadata_count) + this->device.player_state.track.metadata_count = + this->device.player_state.track.full_metadata_count; + if (trackQueue->preloadedTracks.size()) { + trackQueue->preloadedTracks.pop_front(); + if (currentTracks.size() > + (trackQueue->preloadedTracks.size() + offset)) { + while (currentTracks.size() > + trackQueue->preloadedTracks.size() + offset && + trackQueue->preloadedTracks.size() < 3) { + trackQueue->preloadedTracks.push_back( + std::make_shared( + currentTracks[offset + trackQueue->preloadedTracks.size()], + this->ctx, 0)); + } + } + offset++; + } + } else if (trackQueue->preloadedTracks[0]->trackMetrics->getPosition() >= + 3000 && + offset > 1) { + std::scoped_lock lock(trackQueue->tracksMutex); + trackQueue->preloadedTracks.pop_back(); + offset--; + trackQueue->preloadedTracks.push_front(std::make_shared( + currentTracks[offset - 1], this->ctx, 0)); + } else { + if (trackQueue->preloadedTracks.size()) + trackQueue->preloadedTracks[0]->requestedPosition = 0; + } + if (trackQueue->preloadedTracks.size() && + currentTracks.size() < offset + trackQueue->preloadedTracks.size()) { + playerContext->resolveTracklist(metadata_map, reloadTrackList); + } + if (!trackQueue->preloadedTracks.size()) + this->trackPlayer->stop(); + else if (!notify) + trackPlayer->resetState(); +} + +void DeviceStateHandler::parseCommand(std::vector& data) { + if (data.size() <= 2) + return; + auto jsonResult = nlohmann::json::parse(data); + + if (jsonResult.find("message_id") != jsonResult.end()) + last_message_id = jsonResult["message_id"].get(); + + auto command = jsonResult.find("command"); + if (command != jsonResult.end()) { + if (command->find("endpoint") == command->end()) + return; + CSPOT_LOG(debug, "Parsing new command, endpoint : %s", + command->at("endpoint").get().c_str()); + + auto options = command->find("options"); + + if (command->at("endpoint") == "transfer") { + if (is_active) + return; + if (options != command->end()) { + if (options->find("restore_paused") != + options->end()) { //"restore"==play + if (!is_active && options->at("restore_paused") == "restore") { + started_playing_at = this->ctx->timeProvider->getSyncedTimestamp(); + is_active = true; + } + } + } + this->playerContext->radio_offset = 0; + this->device.player_state.has_is_playing = true; + this->device.player_state.is_playing = true; + this->device.player_state.has_timestamp = true; + this->device.player_state.timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + if (!is_active) { + started_playing_at = this->ctx->timeProvider->getSyncedTimestamp(); + is_active = true; + } + auto logging_params = command->find("logging_params"); + if (logging_params != command->end()) { + metadata_map.clear(); + if (logging_params->find("page_instance_ids") != + logging_params->end()) { + metadata_map.push_back(std::make_pair( + "page_instance_id", + logging_params->at("page_instance_ids")[0].get())); + } + + if (logging_params->find("interaction_ids") != logging_params->end()) { + metadata_map.push_back(std::make_pair( + "interaction_id", + logging_params->at("interaction_ids")[0].get())); + } + } + auto responseHandler = [this](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return; + std::scoped_lock lock(trackQueue->tracksMutex); + cspot::TrackReference::clearProvidedTracklist(¤tTracks); + currentTracks = {}; + Cluster cluster = {}; + for (int i = this->device.player_state.context_metadata_count - 1; + i >= 0; i--) { + unreference(this->device.player_state.context_metadata[i].key); + unreference(this->device.player_state.context_metadata[i].value); + } + free(this->device.player_state.context_metadata); + this->device.player_state.context_metadata = NULL; + this->device.player_state.context_metadata_count = 0; + device.player_state.track = ProvidedTrack_init_zero; + device.player_state.next_tracks.arg = NULL; + if (device.player_state.has_restrictions) + pb_release(Restrictions_fields, &device.player_state.restrictions); + device.player_state.restrictions = Restrictions_init_zero; + device.player_state.has_restrictions = false; + pb_release(PlayerState_fields, &this->device.player_state); + this->device.player_state = PlayerState_init_zero; + pb_release(Cluster_fields, &cluster); + cluster.player_state.next_tracks.funcs.decode = + &cspot::TrackReference::pbDecodeProvidedTracks; + cluster.player_state.next_tracks.arg = &this->currentTracks; + + pbDecode(cluster, Cluster_fields, res.parts[0]); + this->device.player_state = cluster.player_state; + cluster.player_state = PlayerState_init_zero; + pb_release(Cluster_fields, &cluster); + offsetFromStartInMillis = device.player_state.position_as_of_timestamp; + + std::vector random_bytes; + static std::uniform_int_distribution d(0, 255); + for (int i = 0; i < 16; i++) { + random_bytes.push_back(d(ctx->rng)); + } + unreference(this->device.player_state.session_id); + this->device.player_state.session_id = + strdup(bytesToHexString(random_bytes).c_str()); + + unreference(this->device.player_state.playback_id); + random_bytes.clear(); + for (int i = 0; i < 16; i++) { + random_bytes.push_back(d(ctx->rng)); + } + this->device.player_state.playback_id = + strdup(base64Encode(random_bytes).c_str()); + + this->currentTracks.insert(this->currentTracks.begin(), + this->device.player_state.track); + offset = 1; + + queuePacket = {&offset, ¤tTracks}; + this->putDeviceState( + PutStateReason::PutStateReason_PLAYER_STATE_CHANGED); + + trackQueue->preloadedTracks.clear(); + reloadPreloadedTracks = true; + playerContext->resolveTracklist(metadata_map, reloadTrackList, true); + }; + this->ctx->session->execute(MercurySession::RequestType::GET, + "hm://connect-state/v1/cluster", + responseHandler); + } else if (this->is_active) { + if (command->at("endpoint") == "play") { + handler->trackPlayer->stop(); + sendCommand(CommandType::DEPLETED); + playerContext->radio_offset = 0; + std::scoped_lock lock(trackQueue->tracksMutex); + trackQueue->preloadedTracks.clear(); + uint8_t queued = 0; + ProvidedTrack track = ProvidedTrack_init_zero; + if (!this->device.player_state.is_playing) { + this->device.player_state.is_playing = true; + this->device.player_state.has_track = true; + } + for (int i = 0; i < currentTracks.size(); i++) { + if (i > this->offset || + strcmp(currentTracks[i].provider, "queue") != 0) { + if (currentTracks[i].full_metadata_count > + currentTracks[i].metadata_count) + currentTracks[i].metadata_count = + currentTracks[i].full_metadata_count; + pb_release(ProvidedTrack_fields, ¤tTracks[i]); + } else + queued++; + } + if (queued) { + currentTracks.erase(currentTracks.begin()); + currentTracks.erase(currentTracks.begin() + queued, + currentTracks.end()); + } else + currentTracks.clear(); + + auto logging_params = command->find("logging_params"); + if (logging_params != command->end()) { + metadata_map.clear(); + if (logging_params->find("page_instance_ids") != + logging_params->end()) { + metadata_map.push_back(std::make_pair( + "page_instance_ids", + logging_params->at("page_instance_ids")[0].get())); + } + if (logging_params->find("interaction_ids") != + logging_params->end()) { + metadata_map.push_back(std::make_pair( + "interaction_id", + logging_params->at("interaction_ids")[0].get())); + } + } + + if (command->find("play_origin") != command->end()) { + pb_release(PlayOrigin_fields, &device.player_state.play_origin); + device.player_state.play_origin = PlayOrigin_init_zero; + device.player_state.play_origin.feature_identifier = + PlayerContext::createStringReferenceIfFound( + command->at("play_origin"), "feature_identifier"); + device.player_state.play_origin.feature_version = + PlayerContext::createStringReferenceIfFound( + command->at("play_origin"), "feature_version"); + device.player_state.play_origin.referrer_identifier = + PlayerContext::createStringReferenceIfFound( + command->at("play_origin"), "referrer_identifier"); + } + + auto options = command->find("options"); + int64_t playlist_offset = 0; + if (options != command->end()) { + if (options->find("player_options_override") != options->end()) + device.player_state.options.shuffling_context = + options->at("player_options_override").at("shuffling_context"); + if (options->find("skip_to") != options->end()) { + if (options->at("skip_to").size()) { + if (options->at("skip_to").find("track_index") != + options->at("skip_to").end()) + playlist_offset = options->at("skip_to").at("track_index"); + track.uri = PlayerContext::createStringReferenceIfFound( + options->at("skip_to"), "track_uri"); + track.uid = PlayerContext::createStringReferenceIfFound( + options->at("skip_to"), "track_uid"); + } + } + } + + auto metadata = command->at("context").find("metadata"); + if (metadata != command->at("context").end()) { + if (metadata->find("enhanced_context") != metadata->end()) { + this->device.player_state.options.context_enhancement[0].key = + strdup("context_enhancement"); + this->device.player_state.options.context_enhancement[0].value = + strdup("NONE"); + this->device.player_state.options.context_enhancement_count = 1; + } else if (this->device.player_state.options + .context_enhancement_count) { + for (auto& enhamcement : + this->device.player_state.options.context_enhancement) { + this->unreference(enhamcement.key); + this->unreference(enhamcement.value); + } + this->device.player_state.options.context_enhancement_count = 0; + } + + context_metadata_map.clear(); + for (auto element : metadata->items()) { + if (element.value().size() && element.value() != "" && + element.key() != "canContainArtists.uris") { + context_metadata_map.push_back(std::make_pair( + element.key(), element.value().get())); + } + } + for (int i = this->device.player_state.context_metadata_count - 1; + i >= 0; i--) { + unreference(this->device.player_state.context_metadata[i].key); + unreference(this->device.player_state.context_metadata[i].value); + } + free(this->device.player_state.context_metadata); + this->device.player_state.context_metadata = + (PlayerState_ContextMetadataEntry*)calloc( + context_metadata_map.size(), + sizeof(PlayerState_ContextMetadataEntry)); + for (int i = 0; i < context_metadata_map.size(); i++) { + this->device.player_state.context_metadata[i].key = + strdup(context_metadata_map[i].first.c_str()); + this->device.player_state.context_metadata[i].value = + strdup(context_metadata_map[i].second.c_str()); + } + this->device.player_state.context_metadata_count = + context_metadata_map.size(); + } + + unreference(this->device.player_state.context_uri); + this->device.player_state.context_uri = + PlayerContext::createStringReferenceIfFound(command->at("context"), + "uri"); + unreference(this->device.player_state.context_url); + this->device.player_state.context_url = + PlayerContext::createStringReferenceIfFound(command->at("context"), + "url"); + + reloadPreloadedTracks = true; + this->trackPlayer->start(); + uint8_t metadata_offset = 0; + for (auto metadata_entry : metadata_map) { + track.metadata[metadata_offset].key = + strdup(metadata_entry.first.c_str()); + track.metadata[metadata_offset].value = + strdup(metadata_entry.second.c_str()); + metadata_offset++; + } + + if (command->at("context").find("pages") != + command->at("context").end() && + command->at("context").at("pages")[0]["tracks"].size() > + playlist_offset) { + //populate first tarck + if (track.uri == NULL) { + track.uri = PlayerContext::createStringReferenceIfFound( + command->at("context")["pages"][0]["tracks"][playlist_offset], + "uri"); + track.uid = PlayerContext::createStringReferenceIfFound( + command->at("context")["pages"][0]["tracks"][playlist_offset], + "uid"); + } + if (command->at("context")["pages"][0]["tracks"][playlist_offset] + .find("metadata") != + command->at("context")["pages"][0]["tracks"][playlist_offset] + .end()) { + for (auto metadata_entry : + command->at("context")["pages"][0]["tracks"][playlist_offset] + .at("metadata") + .items()) { + track.metadata[metadata_offset].key = + strdup(metadata_entry.key().c_str()); + track.metadata[metadata_offset].value = + strdup(((std::string)metadata_entry.value()).c_str()); + metadata_offset++; + } + } + } + track.full_metadata_count = metadata_offset; + track.metadata_count = metadata_offset; + track.provider = strdup("context"); + currentTracks.insert(currentTracks.begin(), track); + device.player_state.track = track; + offset = 1; + playerContext->resolveTracklist(context_metadata_map, reloadTrackList, + true); + } else if (command->at("endpoint") == "pause") { + device.player_state.is_paused = true; + device.player_state.has_is_paused = true; + this->putPlayerState(); + sendCommand(CommandType::PAUSE); + } else if (command->at("endpoint") == "resume") { + device.player_state.is_paused = false; + device.player_state.has_is_paused = true; + this->putPlayerState(); + sendCommand(CommandType::PLAY); + } else if (command->at("endpoint") == "skip_next") { + ctx->playbackMetrics->end_reason = PlaybackMetrics::FORWARD_BTN; + needsToBeSkipped = false; + if (command->find("track") == command->end()) + skip(CommandType::SKIP_NEXT, false); + else { + std::scoped_lock lock(playerContext->trackListMutex); + offset = 0; + for (auto track : currentTracks) { + if (strcmp(command->find("track") + ->at("uri") + .get() + .c_str(), + track.uri) == 0) + break; + offset++; + } + trackQueue->preloadedTracks.clear(); + + this->device.player_state.track = currentTracks[offset]; + for (auto i = offset; + i < (currentTracks.size() < 3 + offset ? currentTracks.size() + : 3 + offset) + + offset; + i++) { + trackQueue->preloadedTracks.push_back( + std::make_shared(currentTracks[i], + this->ctx, 0)); + } + offset++; + trackPlayer->resetState(); + } + sendCommand(CommandType::SKIP_NEXT); + } else if (command->at("endpoint") == "skip_prev") { + ctx->playbackMetrics->end_reason = PlaybackMetrics::BACKWARD_BTN; + needsToBeSkipped = false; + skip(CommandType::SKIP_PREV, false); + sendCommand(CommandType::SKIP_PREV); + + } else if (command->at("endpoint") == "seek_to") { + +#ifndef CONFIG_BELL_NOCODEC + needsToBeSkipped = false; +#endif + if (command->at("relative") == "beginning") { //relative + this->device.player_state.has_position_as_of_timestamp = true; + this->device.player_state.position_as_of_timestamp = + command->at("value").get(); + this->device.player_state.timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + this->trackPlayer->seekMs(command->at("value").get()); + } else if (command->at("relative") == "current") { + this->device.player_state.has_position_as_of_timestamp = true; + this->device.player_state.position_as_of_timestamp = + command->at("value").get() + + command->at("position").get(); + this->trackPlayer->seekMs( + this->device.player_state.position_as_of_timestamp); + this->device.player_state.timestamp = + this->ctx->timeProvider->getSyncedTimestamp(); + } + sendCommand( + CommandType::SEEK, + (int32_t)this->device.player_state.position_as_of_timestamp); + this->putPlayerState(); + } else if (command->at("endpoint") == "add_to_queue") { + std::scoped_lock lock(trackQueue->tracksMutex); + uint8_t queuedOffset = 0; + //look up already queued tracks + for (uint8_t i = offset; i < currentTracks.size(); i++) { + if (strcmp(currentTracks[i].provider, "queue") != 0) + break; + queuedOffset++; + } + + ProvidedTrack track = {}; + track.uri = strdup( + command->find("track")->at("uri").get().c_str()); + track.provider = strdup("queue"); + this->currentTracks.insert( + this->currentTracks.begin() + offset + queuedOffset, track); + if (queuedOffset < 2) { + trackQueue->preloadedTracks.pop_back(); + trackQueue->preloadedTracks.insert( + trackQueue->preloadedTracks.begin() + 1 + queuedOffset, + std::make_shared( + currentTracks[offset + queuedOffset], this->ctx, 0)); + } +#ifndef CONFIG_BELL_NOCODEC + this->trackPlayer->seekMs( + trackQueue->preloadedTracks[0]->trackMetrics->getPosition()); + sendCommand( + CommandType::SEEK, + (int32_t)this->device.player_state.position_as_of_timestamp); +#endif + this->putPlayerState(); + } else if (command->at("endpoint") == "set_queue") { + std::scoped_lock lock(trackQueue->tracksMutex); + uint8_t queuedOffset = 0, newQueuedOffset = 0; + //look up already queued tracks + for (uint8_t i = offset; i < currentTracks.size(); i++) { + if (strcmp(currentTracks[i].provider, "queue") != 0) + break; + queuedOffset++; + } + auto tracks = command->find("next_tracks"); + if (!command->at("next_tracks").size()) { + for (uint8_t i = offset; i < currentTracks.size(); i++) { + if (strcmp(currentTracks[i].provider, "queue") != 0) + break; + pb_release(ProvidedTrack_fields, ¤tTracks[i]); + currentTracks.erase(currentTracks.begin() + i); + i--; + } + } + if (command->find("next_tracks") != command->end()) { + for (int i = 0; i < command->at("next_tracks").size(); i++) { + if (strcmp(command->at("next_tracks")[i]["uri"] + .get() + .c_str(), + currentTracks[offset + i].uri) != 0) { + if (newQueuedOffset < queuedOffset) { + queuedOffset--; + goto removeTrack; + } else if (command->at("next_tracks")[i]["provider"] == "queue") { + ProvidedTrack track = {}; + track.uri = strdup(command->at("next_tracks")[i]["uri"] + .get() + .c_str()); + track.provider = strdup("queue"); + this->currentTracks.insert( + this->currentTracks.begin() + offset + i, track); + continue; + } + removeTrack:; + pb_release(ProvidedTrack_fields, ¤tTracks[offset + i]); + currentTracks.erase(currentTracks.begin() + offset + i); + if (strcmp(currentTracks[offset + i].provider, "queue") != 0 || + strcmp(command->at("next_tracks")[i]["uri"] + .get() + .c_str(), + currentTracks[offset + i].uri) == 0) + break; + i--; + } else if (command->at("next_tracks")[i]["provider"] == "queue") + newQueuedOffset++; + } + } + if (queuedOffset < 2 || newQueuedOffset < 2) { + trackQueue->preloadedTracks.clear(); + while (trackQueue->preloadedTracks.size() < 3) + trackQueue->preloadedTracks.push_back( + std::make_shared( + currentTracks[offset + trackQueue->preloadedTracks.size() - + 1], + this->ctx, 0)); + } +#ifndef CONFIG_BELL_NOCODEC + this->trackPlayer->seekMs( + trackQueue->preloadedTracks[0]->trackMetrics->getPosition()); + sendCommand( + CommandType::SEEK, + (int32_t)this->device.player_state.position_as_of_timestamp); +#endif + this->putPlayerState(); + } else if (command->at("endpoint") == "update_context") { + unreference(this->device.player_state.session_id); + this->device.player_state.session_id = + PlayerContext::createStringReferenceIfFound(*command, "session_id"); + + auto context = command->find("context"); + if (context != command->end()) { + if (context_metadata_map.size()) + context_metadata_map.clear(); + context_uri = context->find("uri") != context->end() + ? context->at("uri").get() + : " "; + context_url = context->find("url") != context->end() + ? context->at("url").get() + : " "; + auto metadata = context->find("metadata"); + if (metadata != context->end()) { + for (auto element : metadata->items()) { + if (element.value().size() && element.value() != "") { + context_metadata_map.push_back(std::make_pair( + element.key(), element.value().get())); + } + } + } + } + } else if (command->at("endpoint") == "set_shuffling_context") { + if (context_uri.size()) { + unreference(this->device.player_state.context_uri); + this->device.player_state.context_uri = strdup(context_uri.c_str()); + } + if (context_url.size()) { + unreference(this->device.player_state.context_url); + this->device.player_state.context_url = strdup(context_url.c_str()); + } + for (int i = this->device.player_state.context_metadata_count - 1; + i >= 0; i--) { + unreference(this->device.player_state.context_metadata[i].key); + unreference(this->device.player_state.context_metadata[i].value); + } + free(this->device.player_state.context_metadata); + this->device.player_state.context_metadata = + (PlayerState_ContextMetadataEntry*)calloc( + context_metadata_map.size(), + sizeof(PlayerState_ContextMetadataEntry)); + for (int i = 0; i < context_metadata_map.size(); i++) { + this->device.player_state.context_metadata[i].key = + strdup(context_metadata_map[i].first.c_str()); + this->device.player_state.context_metadata[i].value = + strdup(context_metadata_map[i].second.c_str()); + } + this->device.player_state.context_metadata_count = + context_metadata_map.size(); + + this->device.player_state.has_options = true; + this->device.player_state.options.has_shuffling_context = true; + if (command->find("value").value()) + this->device.player_state.options.shuffling_context = true; + else + this->device.player_state.options.shuffling_context = false; + if (strchr(this->device.player_state.context_url, '?') != NULL) { + this->device.player_state.options.context_enhancement[0].key = + strdup("context_enhancement"); + this->device.player_state.options.context_enhancement[0].value = + strdup("NONE"); + this->device.player_state.options.context_enhancement_count = 1; + } else { + if (this->device.player_state.options.context_enhancement_count) { + unreference( + this->device.player_state.options.context_enhancement[0].key); + unreference( + this->device.player_state.options.context_enhancement[0].value); + this->device.player_state.options.context_enhancement_count = 0; + } + } + std::scoped_lock lock(trackQueue->tracksMutex); + playerStateChanged = true; + this->trackQueue->preloadedTracks.erase( + this->trackQueue->preloadedTracks.begin(), + this->trackQueue->preloadedTracks.end()); + uint8_t queued = 0; + for (int i = offset; i < currentTracks.size(); i++) { + if (strcmp(currentTracks[i].provider, "queue") != 0) { + if (currentTracks[i].full_metadata_count > + currentTracks[i].metadata_count) + currentTracks[i].metadata_count = + currentTracks[i].full_metadata_count; + pb_release(ProvidedTrack_fields, ¤tTracks[i]); + } else + queued++; + } + currentTracks.erase(currentTracks.begin() + offset + queued, + currentTracks.end()); + playerContext->resolveTracklist(metadata_map, reloadTrackList, true); + sendCommand(CommandType::SET_SHUFFLE, + (int32_t)(this->device.player_state.options + .context_enhancement_count + ? 2 + : this->device.player_state.options + .shuffling_context)); +#ifndef CONFIG_BELL_NOCODEC + this->trackPlayer->seekMs( + trackQueue->preloadedTracks[0]->trackMetrics->getPosition()); + sendCommand( + CommandType::SEEK, + (int32_t)this->device.player_state.position_as_of_timestamp); +#endif + } else if (command->at("endpoint") == "set_options") { + + if (this->device.player_state.options.repeating_context != + command->at("repeating_context").get()) { + uint8_t release = 0; + for (int i = offset; i < currentTracks.size(); i++) + if (strcmp(currentTracks[i].uri, "spotify:delimiter") == 0 || + strcmp(currentTracks[i].provider, "autoplay") == 0) { + release = i; + break; + } + if (release) { + for (int i = release; i < currentTracks.size(); i++) + cspot::TrackReference::pbReleaseProvidedTrack(¤tTracks[i]); + currentTracks.erase(currentTracks.begin() + release, + currentTracks.end()); + } + + this->device.player_state.options.has_repeating_context = true; + this->device.player_state.options.repeating_context = + command->at("repeating_context").get(); + this->device.player_state.options.repeating_track = + command->at("repeating_track").get(); + this->device.player_state.options.has_repeating_track = true; + playerStateChanged = true; + this->playerContext->resolveTracklist(metadata_map, reloadTrackList, + true); + } else { + this->device.player_state.options.has_repeating_context = true; + this->device.player_state.options.repeating_context = + command->at("repeating_context").get(); + this->device.player_state.options.repeating_track = + command->at("repeating_track").get(); + this->device.player_state.options.has_repeating_track = true; + this->putPlayerState(); + } + if (this->device.player_state.options.repeating_context) + sendCommand( + CommandType::SET_REPEAT, + (int32_t)(this->device.player_state.options.repeating_context + ? 2 + : this->device.player_state.options + .repeating_track)); + } else + CSPOT_LOG(error, "Unknown command: %s", + &command->at("endpoint").get()[0]); + return; + } + } +} +void DeviceStateHandler::sendCommand(CommandType type, CommandData data) { + Command command; + command.commandType = type; + command.data = data; + stateCallback(command); +} \ No newline at end of file diff --git a/cspot/src/EventManager.cpp b/cspot/src/EventManager.cpp new file mode 100644 index 00000000..3b292fe7 --- /dev/null +++ b/cspot/src/EventManager.cpp @@ -0,0 +1,284 @@ +#include "EventManager.h" +#include "CSpotContext.h" // for Context::ConfigState, Context (ptr o... +#include "Logger.h" // for CSPOT_LOG +#include "TrackQueue.h" + +using namespace cspot; + +static std::string reason_text[11] = { + "trackdone", "trackerror", "fwdbtn", "backbtn", "endplay", "playbtn", + "clickrow", "logout", "appload", "remote", ""}; + +TrackMetrics::TrackMetrics(std::shared_ptr ctx, uint64_t pos) { + this->ctx = ctx; + timestamp = ctx->timeProvider->getSyncedTimestamp(); + currentInterval = std::make_shared(timestamp, pos); +} + +void TrackMetrics::endInterval(uint64_t pos) { + // end Interval + currentInterval->length = + this->ctx->timeProvider->getSyncedTimestamp() - currentInterval->start; + currentInterval->end = currentInterval->position + currentInterval->length; + totalAmountPlayed += currentInterval->length; + // add skipped time + if (pos != 0) { + if (pos > currentInterval->position + currentInterval->length) + skipped_forward.add( + pos - (currentInterval->position + currentInterval->length)); + else + skipped_backward.add( + (currentInterval->position + currentInterval->length) - pos); + } + if (currentInterval->length > longestInterval) + longestInterval = currentInterval->length; + intervals = + addInterval(intervals, {currentInterval->position, currentInterval->end}); +} + +void TrackMetrics::pauseInterval(uint64_t pos, bool pause) { + // end Interval + if (pause) { + currentInterval->length = + this->ctx->timeProvider->getSyncedTimestamp() - currentInterval->start; + currentInterval->end = currentInterval->position + currentInterval->length; + totalAmountPlayed += currentInterval->length; + // add skipped time + if (pos != 0) { + if (pos > currentInterval->position + currentInterval->length) + skipped_forward.add( + pos - (currentInterval->position + currentInterval->length)); + else + skipped_backward.add( + (currentInterval->position + currentInterval->length) - pos); + } + if (currentInterval->length > longestInterval) + longestInterval = currentInterval->length; + intervals = addInterval(intervals, + {currentInterval->position, currentInterval->end}); + } else { + currentInterval = std::make_shared( + this->ctx->timeProvider->getSyncedTimestamp(), pos); + } +} + +uint64_t TrackMetrics::getPosition(bool paused) { + return (currentInterval->position + + (paused ? currentInterval->length + : (this->ctx->timeProvider->getSyncedTimestamp() - + currentInterval->start))); +} + +void TrackMetrics::startTrack() { + trackHeaderTime = this->ctx->timeProvider->getSyncedTimestamp(); + audioKeyTime = trackHeaderTime - timestamp; +} + +void TrackMetrics::startTrackDecoding() { + trackHeaderTime = + this->ctx->timeProvider->getSyncedTimestamp() - trackHeaderTime; +} + +void TrackMetrics::startTrackPlaying(uint64_t pos) { + trackLatency = this->ctx->timeProvider->getSyncedTimestamp() - audioKeyTime; + currentInterval = std::make_shared( + this->ctx->timeProvider->getSyncedTimestamp(), pos); +} + +void TrackMetrics::endTrack() { + endInterval(0); + for (const auto& interval : intervals) + totalMsOfPlayedTrack += interval.second - interval.first; + totalAmountOfPlayTime = + this->ctx->timeProvider->getSyncedTimestamp() - timestamp; +} + +void TrackMetrics::newPosition(uint64_t pos) { + if (pos == currentInterval->position + currentInterval->length) + return; + endInterval(pos); + currentInterval = std::make_shared( + this->ctx->timeProvider->getSyncedTimestamp(), pos); +} + +std::string PlaybackMetrics::get_source_from_context() { + if (context_uri != "") { + if (context_uri.find("playlist") != std::string::npos) + return "playlist"; + else if (context_uri.find("collection") != std::string::npos) + return "your_library"; + else if (context_uri.find("artist") != std::string::npos) + return "artist"; + else if (context_uri.find("album") != std::string::npos) + return "album"; + else if (context_uri.find("track") != std::string::npos) + return "track"; + } + return ""; +} +std::string PlaybackMetrics::get_end_source() { + end_source = get_source_from_context(); + return end_source; +} +std::vector PlaybackMetrics::sendEvent( + std::shared_ptr track) { + std::string data; + std::vector msg; + CSPOT_LOG(debug, "Sending playbackend event"); + std::string requestUrl = "hm://event-service/v1/events"; + + append(&msg, "12"); + append(&msg, "45"); + append(&msg, std::to_string(seqNum++)); + append(&msg, this->ctx->config.deviceId); + append(&msg, track->identifier); //PLAYBACKiD + append(&msg, "00000000000000000000000000000000"); //parent_playback_id + append(&msg, start_source); + append( + &msg, + reason_text[(uint8_t)start_reason]); //remote when taken over by anyone + append( + &msg, + end_source == "" + ? get_end_source() + : end_source); //free-tier-artist / playlist / your_library .com.spotify.gaia / artist + append(&msg, + reason_text[(uint8_t)end_reason]); //remote when taken over of anyone + append( + &msg, + std::to_string( + track + ->written_bytes)); //@librespot usually the same size as track->size, if shifted forward, usually shorter, if shifted backward, usually bigger + append(&msg, std::to_string(track->trackMetrics->track_size)); //in bytes + append( + &msg, + std::to_string( + track->trackMetrics + ->totalAmountOfPlayTime)); //total millis from start to end (sometimes a little longer than millis_played) pause has no influence + append(&msg, + std::to_string( + track->trackMetrics->totalAmountPlayed)); //total millis played + append(&msg, + std::to_string(track->trackInfo.duration)); //track duration in millis + append( + &msg, + std::to_string( + track->trackMetrics + ->trackHeaderTime)); //total time of decrypting? often 3 or 4 when nothing played -1 + append(&msg, "0"); // fadeoverlapp? usually 0, but fading is set on + append( + &msg, + "0"); // librespot says, could bee that the first value shows if it is the first played song, usually 0 + append(&msg, "0"); //?? usually 0 + append(&msg, "0"); //?? usually 0 + append(&msg, std::to_string(track->trackMetrics->skipped_backward + .count)); //total times skipped backward + append(&msg, + std::to_string(track->trackMetrics->skipped_backward + .amount)); //total amount of time skipped backward + append(&msg, std::to_string(track->trackMetrics->skipped_forward + .count)); //total times skipped forward + append(&msg, + std::to_string(track->trackMetrics->skipped_forward + .amount)); //total amount of time skipped forward + append( + &msg, + std::to_string( + track->trackMetrics + ->trackLatency)); //randomNumber; biggest value so far 260, usually biggert than 1 //spotify says play latency + append(&msg, "-1"); // usually -1, if paused positive, probablly in seconds + append(&msg, "context"); + append(&msg, std::to_string( + track->trackMetrics + ->audioKeyTime)); //time to get the audiokey? usually -1 + append(&msg, "0"); // usually 0 + append(&msg, "1"); // @librespot audioKey preloaded? usually positive (1) + append(&msg, "0"); //?? usually 0 + append( + &msg, + "0"); //?? usually bigger than 0, if startup(not playing) or takenover "0" + append( + &msg, + "1"); // usually 1 , if taken over 0, if player took over not from the start 0 + append(&msg, + std::to_string( + track->trackMetrics->longestInterval)); //length longest interval + append( + &msg, + std::to_string( + track->trackMetrics + ->totalMsOfPlayedTrack)); //total time since start total millis of song played + append(&msg, "0"); //?? usually 0 + append( + &msg, + "320000"); //CONFIG_CSPOT_AUDIO_FORMAT ? CONFIG_CSPOT_AUDIO_FORMAT == 2 ? "320000" : "160000" : "96000"); // bitrate + append(&msg, context_uri); + append(&msg, "vorbis"); + append( + &msg, + track->trackInfo + .trackId); // sometimes, when commands come from outside, or else, this value is something else and the following one is the gid + append(&msg, ""); + append(&msg, "0"); //?? usually 0 + append(&msg, + std::to_string(track->trackMetrics + ->timestamp)); // unix timestamp when track started + append(&msg, "0"); //?? usually 0 + append(&msg, track->ref.provider); + append( + &msg, + (end_source == "playlist" || end_source == "your_library") + ? "your_library" + : "search"); //std::to_string(this->ctx->referrerIdentifier));//your_library:lybrary_header / autoplay:afterplaylist / search:found in search / find /home:found in home + append( + &msg, + "xpui_2024-05-31_1717155884878_"); //xpui_2024-05-31_1717155884878_ xpui_ + date of version(update) + _ + unix_timestamp probably of update //empty if autoplay + append(&msg, "com.spotify"); + append( + &msg, + "none"); //"transition" : gapless if song ended beforehand inside player + append(&msg, "none"); + append( + &msg, + "local"); // @librespot lastCommandSentByDeviceId , usually"local", if orderd from outside last command ident last comment ident from frame.state + append(&msg, "na"); + append(&msg, "none"); + append( + &msg, + ""); // 3067b220-9721-4489-93b4-118dd3a59b7b //page-instance-id // changing , if radio / autoplay empty + append( + &msg, + ""); // 054dfc5a-0108-4971-b8de-1fd95070e416 //interaction_id // stays still , if radio / autoplay capped + append(&msg, ""); + append(&msg, "5003900000000146"); + append(&msg, ""); + for (int i = 0; i < track->ref.full_metadata_count; i++) + if (strcmp(track->ref.metadata[i].key, "decision_id") == 0) { + append(&msg, track->ref.metadata[i].value); + goto appended_decision_id; + } + append( + &msg, + ""); // decision_id ssp~061a6236e23e1a9847bd9b6ad4cd942eac8d //allways the same , only when radio? / autoplay +appended_decision_id:; + append(&msg, ""); + append(&msg, "0"); //?? usually 0 + append(&msg, "0"); //?? usually 0 + + if (end_reason == END_PLAY) + start_reason = nested_reason; + else + start_reason = end_reason; + start_source = end_source; + +#ifndef CONFIG_HIDDEN + auto responseLambda = [=](MercurySession::Response& res) { + }; + + auto parts = MercurySession::DataParts({msg}); + // Execute the request + ctx->session->execute(MercurySession::RequestType::POST, requestUrl, + responseLambda, parts); +#endif + return msg; +} \ No newline at end of file diff --git a/cspot/src/LoginBlob.cpp b/cspot/src/LoginBlob.cpp index 62c9df14..232a8a90 100644 --- a/cspot/src/LoginBlob.cpp +++ b/cspot/src/LoginBlob.cpp @@ -4,6 +4,7 @@ #include // for initializer_list #include "BellLogger.h" // for AbstractLogger +#include "BellUtils.h" // for getMacAddress #include "ConstantParameters.h" // for brandName, cspot, protoc... #include "Logger.h" // for CSPOT_LOG #include "protobuf/authentication.pb.h" // for AuthenticationType_AUTHE... @@ -15,13 +16,38 @@ #include "nlohmann/json_fwd.hpp" // for json #endif +#include //(for generating unique device id) + using namespace cspot; +std::string sha1_digest(const std::vector& message) { + std::vector digest(20); // SHA1 digest size (160 bits) + mbedtls_sha1_context sha1Context; + + mbedtls_sha1_init(&sha1Context); + mbedtls_sha1_starts(&sha1Context); + mbedtls_sha1_update(&sha1Context, message.data(), message.size()); + mbedtls_sha1_finish(&sha1Context, digest.data()); + mbedtls_sha1_free(&sha1Context); + + // Convert digest to a hex string + std::ostringstream oss; + for (const auto& byte : digest) { + oss << std::hex << std::setw(2) << std::setfill('0') + << static_cast(byte); + } + + return oss.str(); // Return the hex string +} + LoginBlob::LoginBlob(std::string name) { char hash[32]; sprintf(hash, "%016zu", std::hash{}(name)); // base is 142137fd329622137a14901634264e6f332e2411 - this->deviceId = std::string("142137fd329622137a149016") + std::string(hash); + std::string mac_string = bell::getMacAddress(); + CSPOT_LOG(info, "new mac : %s", mac_string.c_str()); + std::vector mac(mac_string.begin(), mac_string.end()); + this->deviceId = sha1_digest(mac); this->crypto = std::make_unique(); this->name = name; diff --git a/cspot/src/MercurySession.cpp b/cspot/src/MercurySession.cpp index 4863472a..3db327d9 100644 --- a/cspot/src/MercurySession.cpp +++ b/cspot/src/MercurySession.cpp @@ -22,7 +22,7 @@ using namespace cspot; MercurySession::MercurySession(std::shared_ptr timeProvider) - : bell::Task("mercury_dispatcher", 4 * 1024, 3, 1) { + : bell::Task("mercury_dispatcher", 32 * 1024, 3, 1) { this->timeProvider = timeProvider; } @@ -51,12 +51,14 @@ void MercurySession::runTask() { } } catch (const std::runtime_error& e) { CSPOT_LOG(error, "Error while receiving packet: %s", e.what()); + connection_lost = true; failAllPending(); if (!isRunning) return; reconnect(); + connection_lost = false; continue; } } @@ -138,7 +140,8 @@ std::string MercurySession::getCountryCode() { void MercurySession::handlePacket() { Packet packet = {}; - + if (connection_lost) + return; this->packetQueue.wtpop(packet, 200); if (executeEstabilishedCallback && this->connectionReadyCallback != nullptr) { @@ -175,26 +178,29 @@ void MercurySession::handlePacket() { CSPOT_LOG(debug, "Received mercury packet"); auto response = this->decodeResponse(packet.data); - if (response.first == static_cast(ResponseFlag::FINAL)) { - auto partial = this->partials.find(response.second); - if (this->callbacks.count(response.second)) { - this->callbacks[response.second](partial->second); - this->callbacks.erase(this->callbacks.find(response.second)); + if (!response.fail) { + if (response.sequenceId >= 0) { + if (this->callbacks.count(response.sequenceId)) { + this->callbacks[response.sequenceId](response); + this->callbacks.erase(this->callbacks.find(response.sequenceId)); + } } - this->partials.erase(partial); + pb_release(Header_fields, &response.mercuryHeader); } break; } case RequestType::SUBRES: { auto response = decodeResponse(packet.data); - if (response.first == static_cast(ResponseFlag::FINAL)) { - auto partial = this->partials.find(response.second); - auto uri = std::string(partial->second.mercuryHeader.uri); - if (this->subscriptions.count(uri) > 0) { - this->subscriptions[uri](partial->second); + if (!response.fail) { + std::string uri(response.mercuryHeader.uri); + for (auto& it : this->subscriptions) { + if (uri.find(it.first) != std::string::npos) { + it.second(response); + break; // Exit loop once subscription is found + } } - this->partials.erase(partial); + pb_release(Header_fields, &response.mercuryHeader); } break; } @@ -222,60 +228,73 @@ void MercurySession::failAllPending() { this->callbacks = {}; } -std::pair MercurySession::decodeResponse( +MercurySession::Response MercurySession::decodeResponse( const std::vector& data) { auto sequenceLength = ntohs(extract(data, 0)); - uint64_t sequenceId; + int64_t sequenceId; uint8_t flag; + Response resp; if (sequenceLength == 2) - sequenceId = ntohs(extract(data, 2)); + sequenceId = ntohs(extract(data, 2)); else if (sequenceLength == 4) - sequenceId = ntohl(extract(data, 2)); + sequenceId = ntohl(extract(data, 2)); else if (sequenceLength == 8) - sequenceId = hton64(extract(data, 2)); + sequenceId = hton64(extract(data, 2)); else - return std::make_pair(0, 0); + return resp; size_t pos = 2 + sequenceLength; flag = (uint8_t)data[pos]; pos++; - auto parts = ntohs(extract(data, pos)); + uint16_t parts = ntohs(extract(data, pos)); pos += 2; - auto partial = partials.find(sequenceId); + auto partial = partials.begin(); + while (partial != partials.end() && partial->sequenceId != sequenceId) + partial++; // if(partial.first == sequenceId) if (partial == partials.end()) { CSPOT_LOG(debug, - "Creating new Mercury Response, seq: %llu, flags: %i, parts: %i", + "Creating new Mercury Response, seq: %lli, flags: %i, parts: %i", sequenceId, flag, parts); - partial = this->partials.insert({sequenceId, Response()}).first; - partial->second.parts = {}; - partial->second.fail = false; + this->partials.push_back(Response()); + partial = partials.end() - 1; + partial->parts = {}; + partial->sequenceId = sequenceId; } else CSPOT_LOG(debug, - "Adding to Mercury Response, seq: %llu, flags: %i, parts: %i", + "Adding to Mercury Response, seq: %lli, flags: %i, parts: %i", sequenceId, flag, parts); uint8_t index = 0; while (parts) { - if (data.size() <= pos || partial->second.fail) + if (data.size() <= pos) break; auto partSize = ntohs(extract(data, pos)); pos += 2; - if (!partial->second.mercuryHeader.has_uri) { - partial->second.fail = false; + if (partial->mercuryHeader.uri == NULL) { auto headerBytes = std::vector(data.begin() + pos, data.begin() + pos + partSize); - pbDecode(partial->second.mercuryHeader, Header_fields, headerBytes); + pbDecode(partial->mercuryHeader, Header_fields, headerBytes); } else { - if (index >= partial->second.parts.size()) - partial->second.parts.push_back(std::vector{}); - partial->second.parts[index].insert(partial->second.parts[index].end(), - data.begin() + pos, - data.begin() + pos + partSize); + if (index >= partial->parts.size()) + partial->parts.push_back(std::vector{}); + partial->parts[index].insert(partial->parts[index].end(), + data.begin() + pos, + data.begin() + pos + partSize); index++; } pos += partSize; parts--; } - return std::make_pair(flag, sequenceId); + if (flag == static_cast(ResponseFlag::FINAL)) { + resp = *partial; + partials.erase(partial); + resp.fail = false; + } + return resp; +} + +void MercurySession::addSubscriptionListener(const std::string& uri, + ResponseCallback subscription) { + this->subscriptions.insert({uri, subscription}); } uint64_t MercurySession::executeSubscription(RequestType method, @@ -287,15 +306,14 @@ uint64_t MercurySession::executeSubscription(RequestType method, RequestTypeMap[method].c_str()); // Encode header - pbPutString(uri, tempMercuryHeader.uri); - pbPutString(RequestTypeMap[method], tempMercuryHeader.method); - - tempMercuryHeader.has_method = true; - tempMercuryHeader.has_uri = true; + pb_release(Header_fields, &tempMercuryHeader); + tempMercuryHeader.uri = strdup(uri.c_str()); + tempMercuryHeader.method = strdup(RequestTypeMap[method].c_str()); // GET and SEND are actually the same. Therefore the override // The difference between them is only in header's method - if (method == RequestType::GET) { + if (method == RequestType::GET || method == RequestType::POST || + method == RequestType::PUT) { method = RequestType::SEND; } @@ -304,8 +322,10 @@ uint64_t MercurySession::executeSubscription(RequestType method, } auto headerBytes = pbEncode(Header_fields, &tempMercuryHeader); + pb_release(Header_fields, &tempMercuryHeader); - this->callbacks.insert({sequenceId, callback}); + if (callback != nullptr) + this->callbacks.insert({sequenceId, callback}); // Structure: [Sequence size] [SequenceId] [0x1] [Payloads number] // [Header size] [Header] [Payloads (size + data)] @@ -379,4 +399,4 @@ uint32_t MercurySession::requestAudioKey(const std::vector& trackId, // @TODO: Handle disconnect } return audioKeySequence - 1; -} +} \ No newline at end of file diff --git a/cspot/src/PlaybackState.cpp b/cspot/src/PlaybackState.cpp deleted file mode 100644 index 72697c2f..00000000 --- a/cspot/src/PlaybackState.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "PlaybackState.h" - -#include // for strdup, memcpy, strcpy, strlen -#include // for uint8_t -#include // for free, NULL, realloc, rand -#include -#include // for shared_ptr -#include // for remove_extent_t -#include // for swap - -#include "BellLogger.h" // for AbstractLogger -#include "CSpotContext.h" // for Context::ConfigState, Context (ptr o... -#include "ConstantParameters.h" // for protocolVersion, swVersion -#include "Logger.h" // for CSPOT_LOG -#include "NanoPBHelper.h" // for pbEncode, pbPutString -#include "Packet.h" // for cspot -#include "pb.h" // for pb_bytes_array_t, PB_BYTES_ARRAY_T_A... -#include "pb_decode.h" // for pb_release -#include "protobuf/spirc.pb.h" - -using namespace cspot; - -PlaybackState::PlaybackState(std::shared_ptr ctx) { - this->ctx = ctx; - innerFrame = {}; - remoteFrame = {}; - - // Prepare callbacks for decoding of remote frame track data - remoteFrame.state.track.funcs.decode = &TrackReference::pbDecodeTrackList; - remoteFrame.state.track.arg = &remoteTracks; - - innerFrame.ident = strdup(ctx->config.deviceId.c_str()); - innerFrame.protocol_version = strdup(protocolVersion); - - // Prepare default state - innerFrame.state.has_position_ms = true; - innerFrame.state.position_ms = 0; - - innerFrame.state.status = PlayStatus_kPlayStatusStop; - innerFrame.state.has_status = true; - - innerFrame.state.position_measured_at = 0; - innerFrame.state.has_position_measured_at = true; - - innerFrame.state.shuffle = false; - innerFrame.state.has_shuffle = true; - - innerFrame.state.repeat = false; - innerFrame.state.has_repeat = true; - - innerFrame.device_state.sw_version = strdup(swVersion); - - innerFrame.device_state.is_active = false; - innerFrame.device_state.has_is_active = true; - - innerFrame.device_state.can_play = true; - innerFrame.device_state.has_can_play = true; - - innerFrame.device_state.volume = ctx->config.volume; - innerFrame.device_state.has_volume = true; - - innerFrame.device_state.name = strdup(ctx->config.deviceName.c_str()); - - // Prepare player's capabilities - addCapability(CapabilityType_kCanBePlayer, 1); - addCapability(CapabilityType_kDeviceType, 4); - addCapability(CapabilityType_kGaiaEqConnectId, 1); - addCapability(CapabilityType_kSupportsLogout, 0); - addCapability(CapabilityType_kSupportsPlaylistV2, 1); - addCapability(CapabilityType_kIsObservable, 1); - addCapability(CapabilityType_kVolumeSteps, 64); - addCapability(CapabilityType_kSupportedContexts, -1, - std::vector({"album", "playlist", "search", - "inbox", "toplist", "starred", - "publishedstarred", "track"})); - addCapability(CapabilityType_kSupportedTypes, -1, - std::vector( - {"audio/track", "audio/episode", "audio/episode+track"})); - innerFrame.device_state.capabilities_count = 8; -} - -PlaybackState::~PlaybackState() { - pb_release(Frame_fields, &innerFrame); - pb_release(Frame_fields, &remoteFrame); -} - -void PlaybackState::setPlaybackState(const PlaybackState::State state) { - switch (state) { - case State::Loading: - // Prepare the playback at position 0 - innerFrame.state.status = PlayStatus_kPlayStatusPause; - innerFrame.state.position_ms = 0; - innerFrame.state.position_measured_at = - ctx->timeProvider->getSyncedTimestamp(); - break; - case State::Playing: - innerFrame.state.status = PlayStatus_kPlayStatusPlay; - innerFrame.state.position_measured_at = - ctx->timeProvider->getSyncedTimestamp(); - break; - case State::Stopped: - break; - case State::Paused: - // Update state and recalculate current song position - innerFrame.state.status = PlayStatus_kPlayStatusPause; - uint32_t diff = ctx->timeProvider->getSyncedTimestamp() - - innerFrame.state.position_measured_at; - this->updatePositionMs(innerFrame.state.position_ms + diff); - break; - } -} - -void PlaybackState::syncWithRemote() { - innerFrame.state.context_uri = (char*)realloc( - innerFrame.state.context_uri, strlen(remoteFrame.state.context_uri) + 1); - - strcpy(innerFrame.state.context_uri, remoteFrame.state.context_uri); - - innerFrame.state.has_playing_track_index = true; - innerFrame.state.playing_track_index = remoteFrame.state.playing_track_index; -} - -bool PlaybackState::isActive() { - return innerFrame.device_state.is_active; -} - -void PlaybackState::setActive(bool isActive) { - innerFrame.device_state.is_active = isActive; - if (isActive) { - innerFrame.device_state.became_active_at = - ctx->timeProvider->getSyncedTimestamp(); - innerFrame.device_state.has_became_active_at = true; - } -} - -void PlaybackState::updatePositionMs(uint32_t position) { - innerFrame.state.position_ms = position; - innerFrame.state.position_measured_at = - ctx->timeProvider->getSyncedTimestamp(); -} - -void PlaybackState::setVolume(uint32_t volume) { - innerFrame.device_state.volume = volume; - ctx->config.volume = volume; -} - -bool PlaybackState::decodeRemoteFrame(std::vector& data) { - pb_release(Frame_fields, &remoteFrame); - - remoteTracks.clear(); - - pbDecode(remoteFrame, Frame_fields, data); - - return true; -} - -std::vector PlaybackState::encodeCurrentFrame(MessageType typ) { - // Prepare current frame info - innerFrame.version = 1; - innerFrame.seq_nr = this->seqNum; - innerFrame.typ = typ; - innerFrame.state_update_id = ctx->timeProvider->getSyncedTimestamp(); - innerFrame.has_version = true; - innerFrame.has_seq_nr = true; - innerFrame.recipient_count = 0; - innerFrame.has_state = true; - innerFrame.has_device_state = true; - innerFrame.has_typ = true; - innerFrame.has_state_update_id = true; - - this->seqNum += 1; - - return pbEncode(Frame_fields, &innerFrame); -} - -// Wraps messy nanopb setters. @TODO: find a better way to handle this -void PlaybackState::addCapability(CapabilityType typ, int intValue, - std::vector stringValue) { - innerFrame.device_state.capabilities[capabilityIndex].has_typ = true; - this->innerFrame.device_state.capabilities[capabilityIndex].typ = typ; - - if (intValue != -1) { - this->innerFrame.device_state.capabilities[capabilityIndex].intValue[0] = - intValue; - this->innerFrame.device_state.capabilities[capabilityIndex].intValue_count = - 1; - } else { - this->innerFrame.device_state.capabilities[capabilityIndex].intValue_count = - 0; - } - - for (int x = 0; x < stringValue.size(); x++) { - pbPutString(stringValue[x], - this->innerFrame.device_state.capabilities[capabilityIndex] - .stringValue[x]); - } - - this->innerFrame.device_state.capabilities[capabilityIndex] - .stringValue_count = stringValue.size(); - - this->capabilityIndex += 1; -} diff --git a/cspot/src/PlayerContext.cpp b/cspot/src/PlayerContext.cpp new file mode 100644 index 00000000..e8da0b59 --- /dev/null +++ b/cspot/src/PlayerContext.cpp @@ -0,0 +1,486 @@ +#include "PlayerContext.h" +#include +#include +#include +#include "MercurySession.h" +#include "protobuf/connect.pb.h" // for PutStateRequest, DeviceState, PlayerState... + +#include "BellLogger.h" // for AbstractLogger +#include "Logger.h" // for CSPOT_LOG +#ifdef BELL_ONLY_CJSON +#include "cJSON.h" +#else +#include "nlohmann/json.hpp" // for basic_json<>::object_t, basic_json +#include "nlohmann/json_fwd.hpp" // for json +#endif + +using namespace cspot; +char* PlayerContext::createStringReferenceIfFound( + nlohmann::json::value_type& jsonObject, const char* key) { + if (jsonObject.find(key) != jsonObject.end()) { + std::string value = jsonObject.at(key).get(); + if (value.size()) + return strdup(value.c_str()); + } + return NULL; +} +void PlayerContext::resolveRadio( + std::vector> metadata_map, + void (*responseFunction)(void*), bool secondTry) { + CSPOT_LOG(debug, "Resolve autoplay context: %s", + secondTry ? tracks->at(0).uri : playerState->context_uri); + std::string requestUrl = + string_format("hm://autoplay-enabled/query?uri=%s", + secondTry ? tracks->at(0).uri : playerState->context_uri); + auto responseHandler = [this, metadata_map, responseFunction, + secondTry](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) { + if (secondTry) + resolveRadio(metadata_map, responseFunction, true); + else + return responseFunction(NULL); + } + std::string resolve_autoplay = + std::string(res.parts[0].begin(), res.parts[0].end()); + std::string requestUrl; + if (radio_offset) + requestUrl = (std::string)next_page_url; + else { + auto trackRef = tracks->end() - 1; + while ( + trackRef != tracks->begin() && + (!trackRef->provider || strcmp(trackRef->provider, "context") != 0)) { + trackRef--; + } + if (strcmp(trackRef->provider, "context") == 0) + requestUrl = string_format( + "hm://radio-apollo/v3/stations/%s?autoplay=true&offset=%i", + &resolve_autoplay[0], trackRef->original_index); + else { + requestUrl = "hm://radio-apollo/v3/tracks/" + + (std::string)playerState->context_uri + + "?autoplay=true&count=50&isVideo=false&prev_tracks="; + uint8_t copiedTracks = 0; + while (trackRef != tracks->end()) { + if (strcmp(trackRef->provider, "autoplay") == 0 && + (trackRef->uri && strrchr(trackRef->uri, ':'))) { + if (copiedTracks) + requestUrl += ","; + requestUrl += (std::string)(strrchr(trackRef->uri, ':') + 1); + copiedTracks++; + } + trackRef++; + } + } + } + auto responseHandler = [this, metadata_map, + responseFunction](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return responseFunction(NULL); + if (!res.parts[0].size()) + return responseFunction(NULL); + std::scoped_lock lock(trackListMutex); + // remove old_tracks, keep 5 tracks in memory + int remove_tracks = ((int)*index) - 5; + if (remove_tracks > 0) { + for (int i = 0; i < remove_tracks; i++) { + if (tracks->at(i).full_metadata_count) + tracks->at(i).metadata_count = tracks->at(i).full_metadata_count; + pb_release(ProvidedTrack_fields, &tracks->at(i)); + } + tracks->erase(tracks->begin(), tracks->begin() + remove_tracks); + } + *index = (uint8_t)(remove_tracks < 0 ? 5 + remove_tracks : 5); + auto jsonResult = nlohmann::json::parse(res.parts[0]); + if (jsonResult.find("uri") != jsonResult.end()) + context_uri = jsonResult.at("uri").get(); + if (next_page_url != NULL) + free(next_page_url); + next_page_url = createStringReferenceIfFound(jsonResult, "next_page_url"); + std::vector> metadata = metadata_map; + metadata.push_back(std::make_pair("context_uri", context_uri)); + metadata.push_back(std::make_pair("entity_uri", context_uri)); + metadata.push_back(std::make_pair("iteration", "0")); + metadata.insert(metadata.begin(), + std::make_pair("autoplay.is_autoplay", "true")); + metadata.push_back(std::make_pair("track_player", "audio")); + metadata.push_back( + std::make_pair("actions.skipping_next_past_track", "resume")); + metadata.push_back( + std::make_pair("actions.skipping_prev_past_track", "resume")); + jsonToTracklist(tracks, metadata, jsonResult["tracks"], "autoplay", 0); + radio_offset++; + responseFunction(NULL); + }; + ctx->session->execute(MercurySession::RequestType::GET, requestUrl, + responseHandler); + }; + ctx->session->execute(MercurySession::RequestType::GET, requestUrl, + responseHandler); +} + +static unsigned long distributionToIndex(std::string d) { + return strtoul(&d[d.find("(") + 1], nullptr, 10); +} + +void PlayerContext::createIndexBasedOnTracklist( + std::vector* tracks, nlohmann::json::value_type& json_tracks, + bool shuffle, uint8_t page) { + //create new index + alternative_index.clear(); + std::vector shuffle_index; + bool smart_shuffle = + (json_tracks.at(0).find("metadata") == json_tracks.at(0).end() || + json_tracks.at(0).find("metadata")->find("shuffle.distribution") == + json_tracks.at(0).find("metadata")->end()) + ? false + : true; + for (int i = 0; i < tracks->size(); i++) { + if (strstr(tracks->at(i).uri, "spotify:delimiter")) { + uint8_t release_offset = 1; + while (i + release_offset < tracks->size()) { + cspot::TrackReference::pbReleaseProvidedTrack( + std::addressof(tracks->at(i + release_offset))); + release_offset++; + } + tracks->erase(tracks->begin() + i, tracks->end()); + break; + } + } + if (smart_shuffle) + alternative_index = std::vector(json_tracks.size()); + for (int i = 0; i < json_tracks.size(); i++) { + if (smart_shuffle) { + alternative_index[distributionToIndex(json_tracks.at(i) + .find("metadata") + ->find("shuffle.distribution") + ->get()) - + 1] = i; + } else if (!shuffle) + alternative_index.push_back(i); + for (auto& track : *tracks) { + if (strcmp(track.uri, + json_tracks.at(i).at("uri").get().c_str()) == 0) { + track.original_index = i; + track.page = page; + if (shuffle && !smart_shuffle) + alternative_index.push_back(i); + goto found_track; + } + } + if (shuffle && !smart_shuffle) + shuffle_index.push_back(i); + found_track:; + } + if (shuffle && !smart_shuffle) { + if (shuffle_index.size()) + ctx->rng = std::default_random_engine{ctx->rd()}; + std::shuffle(shuffle_index.begin(), shuffle_index.end(), ctx->rng); + alternative_index.insert(strstr(tracks->back().uri, "spotify:delimiter") + ? alternative_index.end() + : alternative_index.begin(), + shuffle_index.begin(), shuffle_index.end()); + } +} +uint8_t PlayerContext::jsonToTracklist( + std::vector* tracks, + std::vector> metadata_map, + nlohmann::json::value_type& json_tracks, const char* provider, + int64_t offset, uint8_t page, bool shuffle, bool preloadedTrack) { + if (offset >= json_tracks.size()) + return 0; + bool radio = (strcmp("autoplay", provider) == 0) ? true : false; + uint8_t copiedTracks = 0; + if (!radio && json_tracks.size() != alternative_index.size()) + createIndexBasedOnTracklist(tracks, json_tracks, shuffle, page); + if (shuffle) { + for (int i = 0; i < alternative_index.size(); i++) + if (alternative_index[i] == offset) { + offset = i; + break; + } + } + if (preloadedTrack) + offset++; + while (tracks->size() < MAX_TRACKS && offset < json_tracks.size()) { + + ProvidedTrack new_track = ProvidedTrack_init_zero; + int64_t index = radio ? offset : alternative_index[offset]; + if (index >= json_tracks.size() || index < 0) { + offset++; + continue; + } + auto track = json_tracks.at(index); + new_track.uri = createStringReferenceIfFound(track, "uri"); + new_track.uid = createStringReferenceIfFound(track, "uid"); + new_track.provider = strdup(provider); + uint8_t metadata_offset = 0; + for (auto metadata : metadata_map) { + new_track.metadata[metadata_offset].key = strdup(metadata.first.c_str()); + new_track.metadata[metadata_offset].value = + strdup(metadata.second.c_str()); + metadata_offset++; + } + if (track.find("metadata") != track.end()) { + if (track.at("metadata").find("decision_id") != + track.at("metadata").end()) { + new_track.metadata[metadata_offset].key = strdup("decision_id"); + new_track.metadata[metadata_offset].value = + strdup(std::string(track.at("metadata").at("decision_id")).c_str()); + metadata_offset++; + } + new_track.metadata_count = metadata_offset; + for (auto metadata : track.at("metadata").items()) { + if (metadata.key() != "decision_id" && + metadata.key() != "is_promotional" && + metadata.key() != "is_explicit") { + new_track.metadata[metadata_offset].key = + strdup(metadata.key().c_str()); + new_track.metadata[metadata_offset].value = + strdup(((std::string)metadata.value()).c_str()); + metadata_offset++; + } + } + } + new_track.full_metadata_count = metadata_offset; + if (!radio) + new_track.metadata_count = metadata_offset; + new_track.original_index = index; + new_track.page = page; + tracks->push_back(new_track); + copiedTracks++; + offset++; + } + if (offset == json_tracks.size()) { + ProvidedTrack new_track = ProvidedTrack_init_zero; + new_track.uri = strdup("spotify:delimiter"); + new_track.uid = strdup("delimiter0"); + new_track.provider = strdup("context"); + new_track.removed = strdup("context/delimiter"); + metadata_map.insert(metadata_map.begin(), std::make_pair("hidden", "true")); + metadata_map.push_back( + std::make_pair("actions.skipping_next_past_track", "resume")); + metadata_map.push_back( + std::make_pair("actions.advancing_past_track", "resume")); + metadata_map.push_back(std::make_pair("iteration", "0")); + for (auto metadata : metadata_map) { + new_track.metadata[new_track.metadata_count].key = + strdup(metadata.first.c_str()); + new_track.metadata[new_track.metadata_count].value = + strdup(metadata.second.c_str()); + new_track.metadata_count++; + } + tracks->push_back(new_track); + } + return copiedTracks; +} +void PlayerContext::resolveTracklist( + std::vector> metadata_map, + void (*responseFunction)(void*), bool changed_state) { + //if last track was no radio track, resolve tracklist + //CSPOT_LOG() + CSPOT_LOG(debug, "Resolve tracklist"); + if (changed_state) { + for (int i = 0; i < tracks->size(); i++) { + if (strstr(tracks->at(i).uri, "spotify:delimiter")) { + uint8_t release_offset = 0; + while (i + release_offset < tracks->size()) { + cspot::TrackReference::pbReleaseProvidedTrack( + std::addressof(tracks->at(i + release_offset))); + release_offset++; + } + tracks->erase(tracks->begin() + i, tracks->end()); + break; + } + } + } + if ((playerState->track.provider == NULL || + strcmp(playerState->track.provider, "autoplay")) != 0 && + playerState->context_uri != NULL) { + std::string requestUrl = string_format( + "hm://context-resolve/v1/%s", + (playerState->options.shuffling_context && playerState->context_url) + ? &playerState->context_url[10] + : playerState->context_uri); + auto responseHandler = [this, metadata_map, responseFunction, + changed_state](MercurySession::Response& res) { + if (res.fail || !res.parts.size()) + return; + if (!res.parts[0].size()) + return; + auto jsonResult = nlohmann::json::parse(res.parts[0]); + std::scoped_lock lock(trackListMutex); + uint8_t copy_tracks = 0; + if (tracks->size()) { + // remove old_tracks, keep 5 tracks in memory + int remove_tracks = ((int)*index) - 5; + if (remove_tracks > 0) { + for (int i = 0; i < remove_tracks; i++) { + if (tracks->at(i).full_metadata_count > + tracks->at(i).metadata_count) + tracks->at(i).metadata_count = tracks->at(i).full_metadata_count; + pb_release(ProvidedTrack_fields, &tracks->at(i)); + } + tracks->erase(tracks->begin(), tracks->begin() + remove_tracks); + } + *index = (uint8_t)(remove_tracks < 0 ? 5 + remove_tracks : 5); + + auto trackref = tracks->end() - 1; + //if last track was a queued track/delimiter, try to look for a normal track as lookup reference + while (trackref != tracks->begin() && + (strcmp(trackref->provider, "context") != 0 || + trackref->removed != NULL)) { + trackref--; + } + //if no normal track was found, resolve radio + if (strcmp(trackref->provider, "queue") == 0) + return resolveRadio(metadata_map, responseFunction); + looking_for_playlisttrack:; + //if last track was a smart_shuffled track + if (trackref != tracks->begin()) { + if (trackref->removed != NULL || + strcmp(trackref->provider, "context") != + 0) { //is a delimiter || is queued + trackref--; + goto looking_for_playlisttrack; + } + for (int i = 0; i < trackref->full_metadata_count; i++) + if (trackref->metadata[i].key && + strcmp(trackref->metadata[i].key, "provider") == 0 && + !playerState->options + .context_enhancement_count) { //was a smart_shuffle-track, but smart_shuffle is no more + trackref--; + goto looking_for_playlisttrack; + } + } + if (trackref == tracks->begin() && + strcmp(trackref->uri, "spotify:delimiter") == 0) + return; + //if track available were all smart_shuffle_tracks, load Tracklist from 0; + if (trackref == tracks->begin()) { + + for (int i = 0; + i < (trackref->full_metadata_count > trackref->metadata_count + ? trackref->full_metadata_count + : trackref->metadata_count); + i++) + if ((strcmp(trackref->metadata[i].key, "provider") == 0 && + !playerState->options.context_enhancement_count)) { + jsonToTracklist(tracks, metadata_map, + jsonResult["pages"][0]["tracks"], "context", 0, 0, + playerState->options.shuffling_context, false); + return responseFunction(NULL); + } + } + + //look for trackreference + for (int i = 0; i < jsonResult["pages"].size(); i++) { + int64_t offset = 0; + if (!copy_tracks) { + for (auto track : jsonResult["pages"][i]["tracks"]) { + if (strcmp(track["uri"].get().c_str(), + trackref->uri) == 0) { + copy_tracks = 1; + break; + } + offset++; + } + } + //if trackreference was found + if (copy_tracks) { + if (changed_state) { + createIndexBasedOnTracklist( + tracks, jsonResult["pages"][i]["tracks"], + playerState->options.shuffling_context, i); + if (jsonResult["pages"][i]["tracks"].at(0).find("metadata") != + jsonResult["pages"][i]["tracks"].at(0).end() && + jsonResult["pages"][i]["tracks"] + .at(0) + .find("metadata") + ->find("shuffle.distribution") != + jsonResult["pages"][i]["tracks"] + .at(0) + .find("metadata") + ->end()) { + if (playerState->options.shuffling_context) { + if (alternative_index[0] != offset) { + for (auto& index : alternative_index) + if (index == offset) { + index = alternative_index[0]; + alternative_index[0] = offset; + break; + } + } + } + } + } + copy_tracks = jsonToTracklist( + tracks, metadata_map, jsonResult["pages"][i]["tracks"], + "context", offset, i, playerState->options.shuffling_context, + true); + if (copy_tracks) + break; + } + } + } + if (!copy_tracks) { + if (this->playerState->options.repeating_context || !tracks->size()) { + if (*index >= tracks->size()) { + for (int i = 0; i < tracks->size(); i++) + cspot::TrackReference::pbReleaseProvidedTrack(&tracks->at(i)); + tracks->clear(); + *index = 0; + } else + *index = 1; + createIndexBasedOnTracklist(tracks, jsonResult["pages"][0]["tracks"], + playerState->options.shuffling_context, + 0); + jsonToTracklist(tracks, metadata_map, + jsonResult["pages"][0]["tracks"], "context", 0, 0, + playerState->options.shuffling_context, false); + playerState->track = tracks->back(); + + if (*index >= tracks->size() && tracks->size()) { + ProvidedTrack new_track = ProvidedTrack_init_zero; + new_track.uri = strdup("spotify:delimiter"); + new_track.uid = strdup("uiddelimiter0"); + new_track.provider = strdup("context"); + new_track.removed = strdup("context/delimiter"); + new_track.metadata[new_track.metadata_count].key = strdup("hidden"); + new_track.metadata[new_track.metadata_count].value = strdup("true"); + new_track.metadata_count++; + new_track.metadata[new_track.metadata_count].key = + strdup("actions.skipping_next_past_track"); + new_track.metadata[new_track.metadata_count].value = + strdup("resume"); + new_track.metadata_count++; + new_track.metadata[new_track.metadata_count].key = + strdup("actions.advancing_past_track"); + new_track.metadata[new_track.metadata_count].value = + strdup("resume"); + new_track.metadata_count++; + new_track.metadata[new_track.metadata_count].key = + strdup("iteration"); + new_track.metadata[new_track.metadata_count].value = strdup("0"); + new_track.metadata_count++; + for (auto metadata : metadata_map) { + new_track.metadata[new_track.metadata_count].key = + strdup(metadata.first.c_str()); + new_track.metadata[new_track.metadata_count].value = + strdup(metadata.second.c_str()); + new_track.metadata_count++; + } + + tracks->insert(tracks->begin(), new_track); + } + } else + return resolveRadio(metadata_map, responseFunction); + } + responseFunction(NULL); + }; + ctx->session->execute(MercurySession::RequestType::GET, requestUrl, + responseHandler); + + } else + resolveRadio(metadata_map, responseFunction); +} \ No newline at end of file diff --git a/cspot/src/Session.cpp b/cspot/src/Session.cpp index 74bd0633..8700d33a 100644 --- a/cspot/src/Session.cpp +++ b/cspot/src/Session.cpp @@ -74,8 +74,8 @@ std::vector Session::authenticate(std::shared_ptr blob) { // save auth blob for reconnection purposes authBlob = blob; // prepare authentication request proto - auto data = challenges->prepareAuthPacket(blob->authData, blob->authType, - deviceId, blob->username); + auto data = challenges->prepareAuthPacket( + blob->authData, blob->authType, blob->getDeviceId(), blob->username); // Send login request this->shanConn->sendPacket(LOGIN_REQUEST_COMMAND, data); diff --git a/cspot/src/SpircHandler.cpp b/cspot/src/SpircHandler.cpp deleted file mode 100644 index 8d8add6a..00000000 --- a/cspot/src/SpircHandler.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include "SpircHandler.h" - -#include // for uint8_t -#include // for shared_ptr, make_unique, unique_ptr -#include // for remove_extent_t -#include // for move - -#include "BellLogger.h" // for AbstractLogger -#include "CSpotContext.h" // for Context::ConfigState, Context (ptr only) -#include "Logger.h" // for CSPOT_LOG -#include "MercurySession.h" // for MercurySession, MercurySession::Response -#include "NanoPBHelper.h" // for pbDecode -#include "Packet.h" // for cspot -#include "PlaybackState.h" // for PlaybackState, PlaybackState::State -#include "TrackPlayer.h" // for TrackPlayer -#include "TrackQueue.h" -#include "TrackReference.h" // for TrackReference -#include "Utils.h" // for stringHexToBytes -#include "pb_decode.h" // for pb_release -#include "protobuf/spirc.pb.h" // for Frame, State, Frame_fields, MessageTy... - -using namespace cspot; - -SpircHandler::SpircHandler(std::shared_ptr ctx) { - this->playbackState = std::make_shared(ctx); - this->trackQueue = std::make_shared(ctx, playbackState); - - auto EOFCallback = [this]() { - if (trackQueue->isFinished()) { - sendEvent(EventType::DEPLETED); - } - }; - - auto trackLoadedCallback = [this](std::shared_ptr track, - bool paused = false) { - playbackState->setPlaybackState(paused ? PlaybackState::State::Paused - : PlaybackState::State::Playing); - playbackState->updatePositionMs(track->requestedPosition); - - this->notify(); - - // Send playback start event, pause/unpause per request - sendEvent(EventType::PLAYBACK_START, (int)track->requestedPosition); - sendEvent(EventType::PLAY_PAUSE, paused); - }; - - this->ctx = ctx; - this->trackPlayer = std::make_shared( - ctx, trackQueue, EOFCallback, trackLoadedCallback); - - // Subscribe to mercury on session ready - ctx->session->setConnectedHandler([this]() { this->subscribeToMercury(); }); -} - -void SpircHandler::subscribeToMercury() { - auto responseLambda = [this](MercurySession::Response& res) { - if (res.fail) - return; - - sendCmd(MessageType_kMessageTypeHello); - CSPOT_LOG(debug, "Sent kMessageTypeHello!"); - - // Assign country code - this->ctx->config.countryCode = this->ctx->session->getCountryCode(); - }; - auto subscriptionLambda = [this](MercurySession::Response& res) { - if (res.fail) - return; - CSPOT_LOG(debug, "Received subscription response"); - - this->handleFrame(res.parts[0]); - }; - - ctx->session->executeSubscription( - MercurySession::RequestType::SUB, - "hm://remote/user/" + ctx->config.username + "/", responseLambda, - subscriptionLambda); -} - -void SpircHandler::loadTrackFromURI(const std::string& uri) {} - -void SpircHandler::notifyAudioEnded() { - playbackState->updatePositionMs(0); - notify(); - trackPlayer->resetState(true); -} - -void SpircHandler::notifyAudioReachedPlayback() { - int offset = 0; - - // get HEAD track - auto currentTrack = trackQueue->consumeTrack(nullptr, offset); - - // Do not execute when meta is already updated - if (trackQueue->notifyPending) { - trackQueue->notifyPending = false; - - playbackState->updatePositionMs(currentTrack->requestedPosition); - - // Reset position in queued track - currentTrack->requestedPosition = 0; - } else { - trackQueue->skipTrack(TrackQueue::SkipDirection::NEXT, false); - playbackState->updatePositionMs(0); - - // we moved to next track, re-acquire currentTrack again - currentTrack = trackQueue->consumeTrack(nullptr, offset); - } - - this->notify(); - - sendEvent(EventType::TRACK_INFO, currentTrack->trackInfo); -} - -void SpircHandler::updatePositionMs(uint32_t position) { - playbackState->updatePositionMs(position); - notify(); -} - -void SpircHandler::disconnect() { - this->trackQueue->stopTask(); - this->trackPlayer->stop(); - this->ctx->session->disconnect(); -} - -void SpircHandler::handleFrame(std::vector& data) { - // Decode received spirc frame - playbackState->decodeRemoteFrame(data); - - switch (playbackState->remoteFrame.typ) { - case MessageType_kMessageTypeNotify: { - CSPOT_LOG(debug, "Notify frame"); - - // Pause the playback if another player took control - if (playbackState->isActive() && - playbackState->remoteFrame.device_state.is_active) { - CSPOT_LOG(debug, "Another player took control, pausing playback"); - playbackState->setActive(false); - - this->trackPlayer->stop(); - sendEvent(EventType::DISC); - } - break; - } - case MessageType_kMessageTypeSeek: { - this->trackPlayer->seekMs(playbackState->remoteFrame.position); - - playbackState->updatePositionMs(playbackState->remoteFrame.position); - - notify(); - - sendEvent(EventType::SEEK, (int)playbackState->remoteFrame.position); - break; - } - case MessageType_kMessageTypeVolume: - playbackState->setVolume(playbackState->remoteFrame.volume); - this->notify(); - sendEvent(EventType::VOLUME, (int)playbackState->remoteFrame.volume); - break; - case MessageType_kMessageTypePause: - setPause(true); - break; - case MessageType_kMessageTypePlay: - setPause(false); - break; - case MessageType_kMessageTypeNext: - if (nextSong()) { - sendEvent(EventType::NEXT); - } - break; - case MessageType_kMessageTypePrev: - if (previousSong()) { - sendEvent(EventType::PREV); - } - break; - case MessageType_kMessageTypeLoad: { - this->trackPlayer->start(); - - CSPOT_LOG(debug, "Load frame %d!", playbackState->remoteTracks.size()); - - if (playbackState->remoteTracks.size() == 0) { - CSPOT_LOG(info, "No tracks in frame, stopping playback"); - break; - } - - playbackState->setActive(true); - - playbackState->updatePositionMs(playbackState->remoteFrame.position); - playbackState->setPlaybackState(PlaybackState::State::Playing); - - playbackState->syncWithRemote(); - - // Update track list in case we have a new one - trackQueue->updateTracks(playbackState->remoteFrame.state.position_ms, - true); - - this->notify(); - - // Stop the current track, if any - trackPlayer->resetState(); - break; - } - case MessageType_kMessageTypeReplace: { - CSPOT_LOG(debug, "Got replace frame %d", - playbackState->remoteTracks.size()); - playbackState->syncWithRemote(); - - // 1st track is the current one, but update the position - bool cleared = trackQueue->updateTracks( - playbackState->remoteFrame.state.position_ms + - ctx->timeProvider->getSyncedTimestamp() - - playbackState->innerFrame.state.position_measured_at, - false); - - this->notify(); - - // need to re-load all if streaming track is completed - if (cleared) { - sendEvent(EventType::FLUSH); - trackPlayer->resetState(); - } - break; - } - case MessageType_kMessageTypeShuffle: { - CSPOT_LOG(debug, "Got shuffle frame"); - this->notify(); - break; - } - case MessageType_kMessageTypeRepeat: { - CSPOT_LOG(debug, "Got repeat frame"); - this->notify(); - break; - } - default: - break; - } -} - -void SpircHandler::setRemoteVolume(int volume) { - playbackState->setVolume(volume); - notify(); -} - -void SpircHandler::notify() { - this->sendCmd(MessageType_kMessageTypeNotify); -} - -bool SpircHandler::skipSong(TrackQueue::SkipDirection dir) { - bool skipped = trackQueue->skipTrack(dir); - - // Reset track state - trackPlayer->resetState(!skipped); - - // send NEXT or PREV event only when successful - return skipped; -} - -bool SpircHandler::nextSong() { - return skipSong(TrackQueue::SkipDirection::NEXT); -} - -bool SpircHandler::previousSong() { - return skipSong(TrackQueue::SkipDirection::PREV); -} - -std::shared_ptr SpircHandler::getTrackPlayer() { - return this->trackPlayer; -} - -void SpircHandler::sendCmd(MessageType typ) { - // Serialize current player state - auto encodedFrame = playbackState->encodeCurrentFrame(typ); - - auto responseLambda = [=](MercurySession::Response& res) { - }; - auto parts = MercurySession::DataParts({encodedFrame}); - ctx->session->execute(MercurySession::RequestType::SEND, - "hm://remote/user/" + ctx->config.username + "/", - responseLambda, parts); -} -void SpircHandler::setEventHandler(EventHandler handler) { - this->eventHandler = handler; -} - -void SpircHandler::setPause(bool isPaused) { - if (isPaused) { - CSPOT_LOG(debug, "External pause command"); - playbackState->setPlaybackState(PlaybackState::State::Paused); - } else { - CSPOT_LOG(debug, "External play command"); - - playbackState->setPlaybackState(PlaybackState::State::Playing); - } - notify(); - sendEvent(EventType::PLAY_PAUSE, isPaused); -} - -void SpircHandler::sendEvent(EventType type) { - auto event = std::make_unique(); - event->eventType = type; - event->data = {}; - eventHandler(std::move(event)); -} - -void SpircHandler::sendEvent(EventType type, EventData data) { - auto event = std::make_unique(); - event->eventType = type; - event->data = data; - eventHandler(std::move(event)); -} diff --git a/cspot/src/TrackPlayer.cpp b/cspot/src/TrackPlayer.cpp index c96f2ec7..e5d6622e 100644 --- a/cspot/src/TrackPlayer.cpp +++ b/cspot/src/TrackPlayer.cpp @@ -5,13 +5,16 @@ #include // for remove_extent_t #include // for vector, vector<>::value_type -#include "BellLogger.h" // for AbstractLogger -#include "BellUtils.h" // for BELL_SLEEP_MS +#include "BellLogger.h" // for AbstractLogger +#include "BellUtils.h" // for BELL_SLEEP_MS +#include "CSpotContext.h" +#include "EventManager.h" #include "Logger.h" // for CSPOT_LOG #include "Packet.h" // for cspot #include "TrackQueue.h" // for CDNTrackStream, CDNTrackStream::TrackInfo #include "WrappedSemaphore.h" // for WrappedSemaphore +#ifndef CONFIG_BELL_NOCODEC #ifdef BELL_VORBIS_FLOAT #define VORBIS_SEEK(file, position) \ (ov_time_seek(file, (double)position / 1000)) @@ -22,14 +25,17 @@ #define VORBIS_READ(file, buffer, bufferSize, section) \ (ov_read(file, buffer, bufferSize, section)) #endif +#endif namespace cspot { struct Context; struct TrackReference; +class PlaybackMetrics; } // namespace cspot using namespace cspot; +#ifndef CONFIG_BELL_NOCODEC static size_t vorbisReadCb(void* ptr, size_t size, size_t nmemb, TrackPlayer* self) { return self->_vorbisRead(ptr, size, nmemb); @@ -47,17 +53,19 @@ static int vorbisSeekCb(TrackPlayer* self, int64_t offset, int whence) { static long vorbisTellCb(TrackPlayer* self) { return self->_vorbisTell(); } +#endif TrackPlayer::TrackPlayer(std::shared_ptr ctx, std::shared_ptr trackQueue, EOFCallback eof, TrackLoadedCallback trackLoaded) - : bell::Task("cspot_player", 48 * 1024, 5, 1) { + : bell::Task("cspot_player", 56 * 1024, 5, 1) { this->ctx = ctx; this->eofCallback = eof; this->trackLoaded = trackLoaded; this->trackQueue = trackQueue; this->playbackSemaphore = std::make_unique(5); +#ifndef CONFIG_BELL_NOCODEC // Initialize vorbis callbacks vorbisFile = {}; vorbisCallbacks = { @@ -66,6 +74,7 @@ TrackPlayer::TrackPlayer(std::shared_ptr ctx, (decltype(ov_callbacks::close_func))&vorbisCloseCb, (decltype(ov_callbacks::tell_func))&vorbisTellCb, }; +#endif } TrackPlayer::~TrackPlayer() { @@ -78,7 +87,10 @@ void TrackPlayer::start() { if (!isRunning) { isRunning = true; startTask(); - } + this->ctx->playbackMetrics->start_reason = PlaybackMetrics::REMOTE; + this->ctx->playbackMetrics->start_source = "unknown"; + } else + this->ctx->playbackMetrics->end_reason = PlaybackMetrics::END_PLAY; } void TrackPlayer::stop() { @@ -99,10 +111,12 @@ void TrackPlayer::resetState(bool paused) { } void TrackPlayer::seekMs(size_t ms) { +#ifndef CONFIG_BELL_NOCODEC if (inFuture) { // We're in the middle of the next track, so we need to reset the player in order to seek resetState(); } +#endif CSPOT_LOG(info, "Seeking..."); this->pendingSeekPositionMs = ms; @@ -111,16 +125,19 @@ void TrackPlayer::seekMs(size_t ms) { void TrackPlayer::runTask() { std::scoped_lock lock(runningMutex); - std::shared_ptr track, newTrack = nullptr; + std::shared_ptr track = nullptr, newTrack = nullptr; int trackOffset = 0; + size_t tracksPlayed = 1; bool eof = false; bool endOfQueueReached = false; while (isRunning) { + bool properStream = true; // Ensure we even have any tracks to play - if (!this->trackQueue->hasTracks() || - (!pendingReset && endOfQueueReached && trackQueue->isFinished())) { + if (!this->trackQueue->preloadedTracks.size() || + (!pendingReset && endOfQueueReached && + this->trackQueue->preloadedTracks.size() == 1)) { this->trackQueue->playableSemaphore->twait(300); continue; } @@ -155,6 +172,7 @@ void TrackPlayer::runTask() { } track = newTrack; + this->ctx->playbackMetrics->trackMetrics = track->trackMetrics; inFuture = trackOffset > 0; @@ -163,18 +181,18 @@ void TrackPlayer::runTask() { if (track->state != QueuedTrack::State::READY) { CSPOT_LOG(error, "Track failed to load, skipping it"); - this->eofCallback(); + this->eofCallback(false); continue; } } - CSPOT_LOG(info, "Got track ID=%s", track->identifier.c_str()); - currentSongPlaying = true; { std::scoped_lock lock(playbackMutex); + bool skipped = 0; + track->trackMetrics->startTrack(); currentTrackStream = track->getAudioFile(); // Open the stream @@ -183,21 +201,61 @@ void TrackPlayer::runTask() { if (pendingReset || !currentSongPlaying) { continue; } + track->trackMetrics->startTrackDecoding(); + track->trackMetrics->track_size = currentTrackStream->getSize(); - if (trackOffset == 0 && pendingSeekPositionMs == 0) { - this->trackLoaded(track, startPaused); - startPaused = false; - } + this->trackLoaded(track, true); + startPaused = false; +#ifndef CONFIG_BELL_NOCODEC int32_t r = ov_open_callbacks(this, &vorbisFile, NULL, 0, vorbisCallbacks); - +#else + size_t start_offset = 0; + size_t write_offset = 0; + while (!start_offset) { + size_t ret = this->currentTrackStream->readBytes(&pcmBuffer[0], + pcmBuffer.size()); + size_t written = 0; + size_t toWrite = ret; + if (!ret) + continue; + while (toWrite) { + written = dataCallback(pcmBuffer.data() + (ret - toWrite), toWrite, + tracksPlayed, 0); + if (written == 0) { + BELL_SLEEP_MS(1000); + } + toWrite -= written; + } + track->written_bytes += ret; + start_offset = seekable_callback(tracksPlayed); + if (this->spaces_available(tracksPlayed) < pcmBuffer.size()) { + BELL_SLEEP_MS(50); + continue; + } + } + float duration_lambda = 1.0 * + (currentTrackStream->getSize() - start_offset) / + track->trackInfo.duration; +#endif if (pendingSeekPositionMs > 0) { track->requestedPosition = pendingSeekPositionMs; +#ifdef CONFIG_BELL_NOCODEC + pendingSeekPositionMs = 0; +#endif } + ctx->playbackMetrics->end_reason = PlaybackMetrics::REMOTE; if (track->requestedPosition > 0) { +#ifndef CONFIG_BELL_NOCODEC VORBIS_SEEK(&vorbisFile, track->requestedPosition); +#else + size_t seekPosition = + track->requestedPosition * duration_lambda + start_offset; + currentTrackStream->seek(seekPosition); + skipped = true; +#endif } eof = false; @@ -208,26 +266,43 @@ void TrackPlayer::runTask() { while (!eof && currentSongPlaying) { // Execute seek if needed if (pendingSeekPositionMs > 0) { - uint32_t seekPosition = pendingSeekPositionMs; + track->requestedPosition = pendingSeekPositionMs; + // Seek to the new position +#ifndef CONFIG_BELL_NOCODEC + VORBIS_SEEK(&vorbisFile, track->requestedPosition); +#else + uint32_t seekPosition = + track->requestedPosition * duration_lambda + start_offset; + currentTrackStream->seek(seekPosition); + skipped = true; +#endif + track->trackMetrics->newPosition(pendingSeekPositionMs); // Reset the pending seek position pendingSeekPositionMs = 0; - - // Seek to the new position - VORBIS_SEEK(&vorbisFile, seekPosition); + this->trackLoaded(track, false); } - long ret = VORBIS_READ(&vorbisFile, (char*)&pcmBuffer[0], - pcmBuffer.size(), ¤tSection); + long ret = +#ifdef CONFIG_BELL_NOCODEC + this->currentTrackStream->readBytes(&pcmBuffer[0], + pcmBuffer.size()); +#else + VORBIS_READ(&vorbisFile, (char*)&pcmBuffer[0], pcmBuffer.size(), + ¤tSection); +#endif - if (ret == 0) { - CSPOT_LOG(info, "EOF"); - // and done :) - eof = true; - } else if (ret < 0) { + if (ret < 0) { CSPOT_LOG(error, "An error has occured in the stream %d", ret); currentSongPlaying = false; + properStream = false; + eof = true; } else { + if (ret == 0) { + CSPOT_LOG(info, "EOF"); + // and done :) + eof = true; + } if (this->dataCallback != nullptr) { auto toWrite = ret; @@ -238,19 +313,33 @@ void TrackPlayer::runTask() { // If reset happened during playback, return if (!currentSongPlaying || pendingReset) break; - +#ifdef CONFIG_BELL_NOCODEC + if (skipped) { + // Reset the pending seek position + skipped = 0; + } +#endif written = dataCallback(pcmBuffer.data() + (ret - toWrite), - toWrite, track->identifier); + toWrite, tracksPlayed +#ifdef CONFIG_BELL_NOCODEC + , + skipped +#endif + ); } if (written == 0) { BELL_SLEEP_MS(50); } toWrite -= written; } + track->written_bytes += ret; } } } + tracksPlayed++; +#ifndef CONFIG_BELL_NOCODEC ov_clear(&vorbisFile); +#endif CSPOT_LOG(info, "Playing done"); @@ -260,15 +349,17 @@ void TrackPlayer::runTask() { } if (eof) { - if (trackQueue->isFinished()) { + if (this->trackQueue->preloadedTracks.size() <= 1) { endOfQueueReached = true; } - - this->eofCallback(); +#ifdef CONFIG_BELL_NOCODEC + this->eofCallback(properStream); +#endif } } } +#ifndef CONFIG_BELL_NOCODEC size_t TrackPlayer::_vorbisRead(void* ptr, size_t size, size_t nmemb) { if (this->currentTrackStream == nullptr) { return 0; @@ -307,7 +398,14 @@ long TrackPlayer::_vorbisTell() { } return this->currentTrackStream->getPosition(); } +#endif -void TrackPlayer::setDataCallback(DataCallback callback) { +void TrackPlayer::setDataCallback(DataCallback callback, + SeekableCallback seekable_callback, + SeekableCallback spaces_available) { this->dataCallback = callback; +#ifdef CONFIG_BELL_NOCODEC + this->seekable_callback = seekable_callback; + this->spaces_available = spaces_available; +#endif } diff --git a/cspot/src/TrackQueue.cpp b/cspot/src/TrackQueue.cpp index 26ec0a27..b81c2b59 100644 --- a/cspot/src/TrackQueue.cpp +++ b/cspot/src/TrackQueue.cpp @@ -5,9 +5,11 @@ #include #include #include +#include #include "AccessKeyFetcher.h" #include "BellTask.h" +#include "BellUtils.h" // for BELL_SLEEP_MS #include "CDNAudioFile.h" #include "CSpotContext.h" #include "HTTPClient.h" @@ -23,6 +25,7 @@ #include "protobuf/metadata.pb.h" using namespace cspot; + namespace TrackDataUtils { bool countryListContains(char* countryList, const char* country) { uint16_t countryList_length = strlen(countryList); @@ -120,14 +123,20 @@ void TrackInfo::loadPbEpisode(Episode* pbEpisode, duration = pbEpisode->duration; } -QueuedTrack::QueuedTrack(TrackReference& ref, +QueuedTrack::QueuedTrack(ProvidedTrack& ref, std::shared_ptr ctx, - uint32_t requestedPosition) - : requestedPosition(requestedPosition), ctx(ctx) { - this->ref = ref; - + int64_t requestedPosition) + : requestedPosition((uint32_t)requestedPosition), ctx(ctx) { + trackMetrics = std::make_shared(ctx, requestedPosition); loadedSemaphore = std::make_shared(); - state = State::QUEUED; + this->ref = ref; + if (ref.uid == NULL || !strstr(ref.uri, "spotify:delimiter")) { + this->gid = base62Decode(ref.uri); + state = State::QUEUED; + } else { + state = State::FAILED; + loadedSemaphore->give(); + } } QueuedTrack::~QueuedTrack() { @@ -141,6 +150,8 @@ QueuedTrack::~QueuedTrack() { if (pendingAudioKeyRequest != 0) { ctx->session->unregisterAudioKey(pendingAudioKeyRequest); } + pb_release(Track_fields, &pbTrack); + pb_release(Episode_fields, &pbEpisode); } std::shared_ptr QueuedTrack::getAudioFile() { @@ -158,7 +169,7 @@ void QueuedTrack::stepParseMetadata(Track* pbTrack, Episode* pbEpisode) { const char* countryCode = ctx->config.countryCode.c_str(); - if (ref.type == TrackReference::Type::TRACK) { + if (gid.first == SpotifyFileType::TRACK) { CSPOT_LOG(info, "Track name: %s", pbTrack->name); CSPOT_LOG(info, "Track duration: %d", pbTrack->duration); @@ -235,8 +246,6 @@ void QueuedTrack::stepParseMetadata(Track* pbTrack, Episode* pbEpisode) { loadedSemaphore->give(); return; } - - // Assign track identifier identifier = bytesToHexString(fileId); state = State::KEY_REQUIRED; @@ -282,9 +291,8 @@ void QueuedTrack::stepLoadCDNUrl(const std::string& accessKey) { std::string requestUrl = string_format( "https://api.spotify.com/v1/storage-resolve/files/audio/interactive/" - "%s?alt=json&product=9", + "%s?alt=json", bytesToHexString(fileId).c_str()); - auto req = bell::HTTPClient::get( requestUrl, {bell::HTTPClient::ValueHeader( {"Authorization", "Bearer " + accessKey})}); @@ -302,7 +310,7 @@ void QueuedTrack::stepLoadCDNUrl(const std::string& accessKey) { cdnUrl = jsonResult["cdnurl"][0]; #endif - CSPOT_LOG(info, "Received CDN URL, %s", cdnUrl.c_str()); + // CSPOT_LOG(info, "Received CDN URL, %s", cdnUrl.c_str()); state = State::READY; loadedSemaphore->give(); } catch (...) { @@ -322,12 +330,11 @@ void QueuedTrack::expire() { void QueuedTrack::stepLoadMetadata( Track* pbTrack, Episode* pbEpisode, std::mutex& trackListMutex, std::shared_ptr updateSemaphore) { - // Prepare request ID - std::string requestUrl = string_format( - "hm://metadata/3/%s/%s", - ref.type == TrackReference::Type::TRACK ? "track" : "episode", - bytesToHexString(ref.gid).c_str()); + std::string requestUrl = + string_format("hm://metadata/3/%s/%s", + gid.first == SpotifyFileType::TRACK ? "track" : "episode", + bytesToHexString(gid.second).c_str()); auto responseHandler = [this, pbTrack, pbEpisode, &trackListMutex, updateSemaphore](MercurySession::Response& res) { @@ -342,7 +349,7 @@ void QueuedTrack::stepLoadMetadata( } // Parse the metadata - if (ref.type == TrackReference::Type::TRACK) { + if (gid.first == SpotifyFileType::TRACK) { pb_release(Track_fields, pbTrack); pbDecode(*pbTrack, Track_fields, res.parts[0]); } else { @@ -356,29 +363,20 @@ void QueuedTrack::stepLoadMetadata( updateSemaphore->give(); }; // Execute the request - pendingMercuryRequest = ctx->session->execute( - MercurySession::RequestType::GET, requestUrl, responseHandler); + if (pbTrack != NULL || pbEpisode != NULL) + pendingMercuryRequest = ctx->session->execute( + MercurySession::RequestType::GET, requestUrl, responseHandler); // Set the state to pending state = State::PENDING_META; } -TrackQueue::TrackQueue(std::shared_ptr ctx, - std::shared_ptr state) - : bell::Task("CSpotTrackQueue", 1024 * 32, 2, 1), - playbackState(state), - ctx(ctx) { +TrackQueue::TrackQueue(std::shared_ptr ctx) + : bell::Task("CSpotTrackQueue", 1024 * 32, 2, 1), ctx(ctx) { accessKeyFetcher = std::make_shared(ctx); processSemaphore = std::make_shared(); playableSemaphore = std::make_shared(); - // Assign encode callback to track list - playbackState->innerFrame.state.track.funcs.encode = - &TrackReference::pbEncodeTrackList; - playbackState->innerFrame.state.track.arg = ¤tTracks; - pbTrack = Track_init_zero; - pbEpisode = Episode_init_zero; - // Start the task startTask(); }; @@ -387,17 +385,6 @@ TrackQueue::~TrackQueue() { stopTask(); std::scoped_lock lock(tracksMutex); - - pb_release(Track_fields, &pbTrack); - pb_release(Episode_fields, &pbEpisode); -} - -TrackInfo TrackQueue::getTrackInfo(std::string_view identifier) { - for (auto& track : preloadedTracks) { - if (track->identifier == identifier) - return track->trackInfo; - } - return TrackInfo{}; } void TrackQueue::runTask() { @@ -413,10 +400,9 @@ void TrackQueue::runTask() { // Make sure we have the newest access key accessKey = accessKeyFetcher->getAccessKey(); - int loadedIndex = currentTracksIndex; - // No tracks loaded yet - if (loadedIndex < 0) { + if (!preloadedTracks.size()) { + BELL_SLEEP_MS(50); continue; } else { std::scoped_lock lock(tracksMutex); @@ -425,6 +411,7 @@ void TrackQueue::runTask() { } for (auto& track : trackQueue) { + std::scoped_lock lock(tracksMutex); if (track) { this->processTrack(track); } @@ -444,24 +431,11 @@ std::shared_ptr TrackQueue::consumeTrack( std::shared_ptr prevTrack, int& offset) { std::scoped_lock lock(tracksMutex); - if (currentTracksIndex == -1 || currentTracksIndex >= currentTracks.size()) { + if (!preloadedTracks.size()) { + offset = -1; return nullptr; } - // No previous track, return head - if (prevTrack == nullptr) { - offset = 0; - - return preloadedTracks[0]; - } - - // if (currentTracksIndex + preloadedTracks.size() >= currentTracks.size()) { - // offset = -1; - - // // Last track in queue - // return nullptr; - // } - auto prevTrackIter = std::find(preloadedTracks.begin(), preloadedTracks.end(), prevTrack); @@ -471,20 +445,17 @@ std::shared_ptr TrackQueue::consumeTrack( } else { offset = 0; } - if (offset >= preloadedTracks.size()) { // Last track in preloaded queue return nullptr; } - - // Return the current track return preloadedTracks[offset]; } void TrackQueue::processTrack(std::shared_ptr track) { switch (track->state) { case QueuedTrack::State::QUEUED: - track->stepLoadMetadata(&pbTrack, &pbEpisode, tracksMutex, + track->stepLoadMetadata(&track->pbTrack, &track->pbEpisode, tracksMutex, processSemaphore); break; case QueuedTrack::State::KEY_REQUIRED: @@ -492,145 +463,8 @@ void TrackQueue::processTrack(std::shared_ptr track) { break; case QueuedTrack::State::CDN_REQUIRED: track->stepLoadCDNUrl(accessKey); - - if (track->state == QueuedTrack::State::READY) { - if (preloadedTracks.size() < MAX_TRACKS_PRELOAD) { - // Queue a new track to preload - queueNextTrack(preloadedTracks.size()); - } - } - break; default: // Do not perform any action break; } } - -bool TrackQueue::queueNextTrack(int offset, uint32_t positionMs) { - const int requestedRefIndex = offset + currentTracksIndex; - - if (requestedRefIndex < 0 || requestedRefIndex >= currentTracks.size()) { - return false; - } - - // in case we re-queue current track, make sure position is updated (0) - if (offset == 0 && preloadedTracks.size() && - preloadedTracks[0]->ref == currentTracks[currentTracksIndex]) { - preloadedTracks.pop_front(); - } - - if (offset <= 0) { - preloadedTracks.push_front(std::make_shared( - currentTracks[requestedRefIndex], ctx, positionMs)); - } else { - preloadedTracks.push_back(std::make_shared( - currentTracks[requestedRefIndex], ctx, positionMs)); - } - - return true; -} - -bool TrackQueue::skipTrack(SkipDirection dir, bool expectNotify) { - bool skipped = true; - std::scoped_lock lock(tracksMutex); - - if (dir == SkipDirection::PREV) { - uint64_t position = - !playbackState->innerFrame.state.has_position_ms - ? 0 - : playbackState->innerFrame.state.position_ms + - ctx->timeProvider->getSyncedTimestamp() - - playbackState->innerFrame.state.position_measured_at; - - if (currentTracksIndex > 0 && position < 3000) { - queueNextTrack(-1); - - if (preloadedTracks.size() > MAX_TRACKS_PRELOAD) { - preloadedTracks.pop_back(); - } - - currentTracksIndex--; - } else { - queueNextTrack(0); - } - } else { - if (currentTracks.size() > currentTracksIndex + 1) { - preloadedTracks.pop_front(); - - if (!queueNextTrack(preloadedTracks.size() + 1)) { - CSPOT_LOG(info, "Failed to queue next track"); - } - - currentTracksIndex++; - } else { - skipped = false; - } - } - - if (skipped) { - // Update frame data - playbackState->innerFrame.state.playing_track_index = currentTracksIndex; - - if (expectNotify) { - // Reset position to zero - notifyPending = true; - } - } - - return skipped; -} - -bool TrackQueue::hasTracks() { - std::scoped_lock lock(tracksMutex); - - return currentTracks.size() > 0; -} - -bool TrackQueue::isFinished() { - std::scoped_lock lock(tracksMutex); - return currentTracksIndex >= currentTracks.size() - 1; -} - -bool TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) { - std::scoped_lock lock(tracksMutex); - bool cleared = true; - - // Copy requested track list - currentTracks = playbackState->remoteTracks; - currentTracksIndex = playbackState->innerFrame.state.playing_track_index; - - if (initial) { - // Clear preloaded tracks - preloadedTracks.clear(); - - if (currentTracksIndex < currentTracks.size()) { - // Push a song on the preloaded queue - queueNextTrack(0, requestedPosition); - } - - // We already updated track meta, mark it - notifyPending = true; - - playableSemaphore->give(); - } else if (preloadedTracks[0]->loading) { - // try to not re-load track if we are still loading it - - // remove everything except first track - preloadedTracks.erase(preloadedTracks.begin() + 1, preloadedTracks.end()); - - // Push a song on the preloaded queue - CSPOT_LOG(info, "Keeping current track %d", currentTracksIndex); - queueNextTrack(1); - - cleared = false; - } else { - // Clear preloaded tracks - preloadedTracks.clear(); - - // Push a song on the preloaded queue - CSPOT_LOG(info, "Re-loading current track"); - queueNextTrack(0, requestedPosition); - } - - return cleared; -} diff --git a/cspot/src/TrackReference.cpp b/cspot/src/TrackReference.cpp index 3b3b7031..e83e55b3 100644 --- a/cspot/src/TrackReference.cpp +++ b/cspot/src/TrackReference.cpp @@ -1,28 +1,18 @@ #include "TrackReference.h" #include "NanoPBExtensions.h" -#include "Utils.h" -#include "protobuf/spirc.pb.h" +#include "protobuf/connect.pb.h" using namespace cspot; -static constexpr auto base62Alphabet = - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static std::string empty_string = ""; TrackReference::TrackReference() : type(Type::TRACK) {} void TrackReference::decodeURI() { if (gid.size() == 0) { // Episode GID is being fetched via base62 encoded URI - auto idString = uri.substr(uri.find_last_of(":") + 1, uri.size()); - gid = {0}; - - std::string_view alphabet(base62Alphabet); - for (int x = 0; x < idString.size(); x++) { - size_t d = alphabet.find(idString[x]); - gid = bigNumMultiply(gid, 62); - gid = bigNumAdd(gid, d); - } + gid = base62Decode(uri).second; if (uri.find("episode:") != std::string::npos) { type = Type::EPISODE; @@ -34,119 +24,41 @@ bool TrackReference::operator==(const TrackReference& other) const { return other.gid == gid && other.uri == uri; } -bool TrackReference::pbEncodeTrackList(pb_ostream_t* stream, - const pb_field_t* field, - void* const* arg) { - auto trackQueue = *static_cast*>(*arg); - static TrackRef msg = TrackRef_init_zero; - - // Prepare nanopb callbacks - msg.context.funcs.encode = &bell::nanopb::encodeString; - msg.uri.funcs.encode = &bell::nanopb::encodeString; - msg.gid.funcs.encode = &bell::nanopb::encodeVector; - msg.queued.funcs.encode = &bell::nanopb::encodeBoolean; - - for (auto trackRef : trackQueue) { +bool TrackReference::pbEncodeProvidedTracks(pb_ostream_t* stream, + const pb_field_t* field, + void* const* arg) { + auto trackPacket = (std::pair*>*)(*arg); + if (*trackPacket->first >= trackPacket->second->size() || + !trackPacket->second->size()) + return true; + for (int i = *trackPacket->first; i < trackPacket->second->size(); i++) { if (!pb_encode_tag_for_field(stream, field)) { return false; } - - msg.gid.arg = &trackRef.gid; - msg.uri.arg = &trackRef.uri; - msg.context.arg = &trackRef.context; - msg.queued.arg = &trackRef.queued; - - if (!pb_encode_submessage(stream, TrackRef_fields, &msg)) { + if (!pb_encode_submessage(stream, ProvidedTrack_fields, + &(trackPacket->second->at(i)))) return false; - } + //if there's a delimiter, or the tracks are over the track treshhold + if (trackPacket->second->at(i).removed != NULL || + i - *trackPacket->first >= TRACK_SEND_LIMIT) + return true; } - return true; } -bool TrackReference::pbDecodeTrackList(pb_istream_t* stream, - const pb_field_t* field, void** arg) { - auto trackQueue = static_cast*>(*arg); +bool TrackReference::pbDecodeProvidedTracks(pb_istream_t* stream, + const pb_field_t* field, + void** arg) { + auto trackQueue = static_cast*>(*arg); // Push a new reference - trackQueue->push_back(TrackReference()); + trackQueue->push_back(ProvidedTrack()); auto& track = trackQueue->back(); - bool eof = false; - pb_wire_type_t wire_type; - pb_istream_t substream; - uint32_t tag; - - while (!eof) { - if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) { - // Decoding failed and not eof - if (!eof) { - return false; - } - // EOF - } else { - switch (tag) { - case TrackRef_uri_tag: - case TrackRef_context_tag: - case TrackRef_gid_tag: { - // Make substream - if (!pb_make_string_substream(stream, &substream)) { - - return false; - } - - uint8_t* destBuffer = nullptr; - - // Handle GID - if (tag == TrackRef_gid_tag) { - track.gid.resize(substream.bytes_left); - destBuffer = &track.gid[0]; - } else if (tag == TrackRef_context_tag) { - track.context.resize(substream.bytes_left); - - destBuffer = reinterpret_cast(&track.context[0]); - } else if (tag == TrackRef_uri_tag) { - track.uri.resize(substream.bytes_left); - - destBuffer = reinterpret_cast(&track.uri[0]); - } - - if (!pb_read(&substream, destBuffer, substream.bytes_left)) { - return false; - } - - // Close substream - if (!pb_close_string_substream(stream, &substream)) { - return false; - } - - break; - } - case TrackRef_queued_tag: { - uint32_t queuedValue; - - // Decode boolean - if (!pb_decode_varint32(stream, &queuedValue)) { - return false; - } - - // Cast down to bool - track.queued = (bool)queuedValue; - - break; - } - default: - // Field not known, skip - pb_skip_field(stream, wire_type); - - break; - } - } - } - - // Fill in GID when only URI is provided - track.decodeURI(); + if (!pb_decode(stream, ProvidedTrack_fields, &track)) + return false; + track.full_metadata_count = track.metadata_count; return true; -} +} \ No newline at end of file diff --git a/cspot/src/Utils.cpp b/cspot/src/Utils.cpp index fa5a3d95..dfdd588e 100644 --- a/cspot/src/Utils.cpp +++ b/cspot/src/Utils.cpp @@ -11,6 +11,11 @@ #include #endif +static std::string Base62Alphabet = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static char Base64Alphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + unsigned long long getCurrentTimestamp() { return std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) @@ -28,6 +33,34 @@ uint64_t hton64(uint64_t value) { } } +std::string base64Encode(const std::vector& v) { + std::string ss; + int nLenOut = 0; + int index = 0; + while (index < v.size()) { + size_t decode_size = v.size() - index; + unsigned long n = v[index]; + n <<= 8; + n |= (decode_size > 1) ? v[index + 1] : 0; + n <<= 8; + n |= (decode_size > 2) ? v[index + 2] : 0; + uint8_t m4 = n & 0x3f; + n >>= 6; + uint8_t m3 = n & 0x3f; + n >>= 6; + uint8_t m2 = n & 0x3f; + n >>= 6; + uint8_t m1 = n & 0x3f; + + ss.push_back(Base64Alphabet[m1]); + ss.push_back(Base64Alphabet[m2]); + ss.push_back(decode_size > 1 ? Base64Alphabet[m3] : '='); + ss.push_back(decode_size > 2 ? Base64Alphabet[m4] : '='); + index += 3; + } + return ss; +} + std::vector stringHexToBytes(const std::string& s) { std::vector v; v.reserve(s.length() / 2); @@ -151,4 +184,26 @@ std::string urlDecode(std::string str) { } return encodedString; +} + +std::pair> base62Decode(std::string uri) { + std::vector n = std::vector({0}); + SpotifyFileType type = SpotifyFileType::UNKNOWN; + auto it = uri.begin(); + if (uri.find(":") != std::string::npos) { + if (uri.find("episode:") != std::string::npos) { + type = SpotifyFileType::EPISODE; + } else if (uri.find("track:") != std::string::npos) { + type = SpotifyFileType::TRACK; + } + it += uri.rfind(":") + 1; + } + while (it != uri.end()) { + size_t d = Base62Alphabet.find(*it); + n = bigNumMultiply(n, 62); + n = bigNumAdd(n, d); + it++; + } + + return std::make_pair(type, n); } \ No newline at end of file diff --git a/targets/cli/CliPlayer.cpp b/targets/cli/CliPlayer.cpp index 69cbfba7..38bd39e4 100644 --- a/targets/cli/CliPlayer.cpp +++ b/targets/cli/CliPlayer.cpp @@ -14,13 +14,13 @@ #include "BellDSP.h" // for BellDSP, BellDSP::FadeEffect, BellDS... #include "BellUtils.h" // for BELL_SLEEP_MS #include "CentralAudioBuffer.h" // for CentralAudioBuffer::AudioChunk, Cent... +#include "DeviceStateHandler.h" // for DeviceStateHandler, DeviceStateHandler::CommandType #include "Logger.h" -#include "SpircHandler.h" // for SpircHandler, SpircHandler::EventType -#include "StreamInfo.h" // for BitWidth, BitWidth::BW_16 -#include "TrackPlayer.h" // for TrackPlayer +#include "StreamInfo.h" // for BitWidth, BitWidth::BW_16 +#include "TrackPlayer.h" // for TrackPlayer CliPlayer::CliPlayer(std::unique_ptr sink, - std::shared_ptr handler) + std::shared_ptr handler) : bell::Task("player", 1024, 0, 0) { this->handler = handler; this->audioSink = std::move(sink); @@ -32,54 +32,70 @@ CliPlayer::CliPlayer(std::unique_ptr sink, this->dsp = std::make_shared(this->centralAudioBuffer); #endif - auto hashFunc = std::hash(); - - this->handler->getTrackPlayer()->setDataCallback( - [this, &hashFunc](uint8_t* data, size_t bytes, std::string_view trackId) { - auto hash = hashFunc(trackId); - - return this->centralAudioBuffer->writePCM(data, bytes, hash); - }); + this->handler->trackPlayer->setDataCallback([this](uint8_t* data, + size_t bytes, +#ifdef CONFIG_BELL_NOCODEC + bool STORAGE_VOLATILE, +#endif + size_t trackId) { + return this->centralAudioBuffer->writePCM(data, bytes, trackId); + }); this->isPaused = false; - this->handler->setEventHandler( - [this](std::unique_ptr event) { - switch (event->eventType) { - case cspot::SpircHandler::EventType::PLAY_PAUSE: - if (std::get(event->data)) { - this->pauseRequested = true; - } else { - this->isPaused = false; - this->pauseRequested = false; - } + this->handler->stateCallback = + [this](cspot::DeviceStateHandler::Command event) { + switch (event.commandType) { + case cspot::DeviceStateHandler::CommandType::PAUSE: + this->pauseRequested = true; + break; + case cspot::DeviceStateHandler::CommandType::PLAY: + this->isPaused = false; + this->pauseRequested = false; break; - case cspot::SpircHandler::EventType::FLUSH: { + case cspot::DeviceStateHandler::CommandType::FLUSH: { this->centralAudioBuffer->clearBuffer(); break; } - case cspot::SpircHandler::EventType::DISC: + case cspot::DeviceStateHandler::CommandType::DISC: this->centralAudioBuffer->clearBuffer(); + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + tracks.clear(); + this->playlistEnd = true; break; - case cspot::SpircHandler::EventType::SEEK: + case cspot::DeviceStateHandler::CommandType::SEEK: this->centralAudioBuffer->clearBuffer(); break; - case cspot::SpircHandler::EventType::PLAYBACK_START: - this->isPaused = true; - this->playlistEnd = false; + case cspot::DeviceStateHandler::CommandType::SKIP_NEXT: + case cspot::DeviceStateHandler::CommandType::SKIP_PREV: this->centralAudioBuffer->clearBuffer(); break; - case cspot::SpircHandler::EventType::DEPLETED: + case cspot::DeviceStateHandler::CommandType::PLAYBACK_START: + this->centralAudioBuffer->clearBuffer(); + if (tracks.size()) + tracks.clear(); + this->isPaused = false; + this->playlistEnd = false; + break; + case cspot::DeviceStateHandler::CommandType::PLAYBACK: + tracks.push_back( + std::get>(event.data)); + this->isPaused = false; + this->playlistEnd = false; + break; + case cspot::DeviceStateHandler::CommandType::DEPLETED: + this->centralAudioBuffer->clearBuffer(); this->playlistEnd = true; break; - case cspot::SpircHandler::EventType::VOLUME: { - int volume = std::get(event->data); + case cspot::DeviceStateHandler::CommandType::VOLUME: { + int volume = std::get(event.data); break; } default: break; } - }); + }; startTask(); } @@ -111,15 +127,28 @@ void CliPlayer::runTask() { if (!chunk || chunk->pcmSize == 0) { if (this->playlistEnd) { - this->handler->notifyAudioEnded(); - this->playlistEnd = false; + this->playlistEnd = false; + if (tracks.size()) { + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + tracks.clear(); + } + lastHash = 0; } BELL_SLEEP_MS(10); continue; } else { if (lastHash != chunk->trackHash) { + if (lastHash) { + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + tracks.pop_front(); + this->handler->trackPlayer->eofCallback(true); + } lastHash = chunk->trackHash; - this->handler->notifyAudioReachedPlayback(); + tracks.at(0)->trackMetrics->startTrackPlaying( + tracks.at(0)->requestedPosition); + this->handler->putPlayerState(); } #ifndef BELL_DISABLE_CODECS diff --git a/targets/cli/CliPlayer.h b/targets/cli/CliPlayer.h index 0857a640..65b7f122 100644 --- a/targets/cli/CliPlayer.h +++ b/targets/cli/CliPlayer.h @@ -7,29 +7,31 @@ #include // for mutex #include // for string -#include "AudioSink.h" // for AudioSink -#include "BellTask.h" // for Task +#include "AudioSink.h" // for AudioSink +#include "BellTask.h" // for Task +#include "DeviceStateHandler.h" // for DeviceStateHandler namespace bell { class BellDSP; class CentralAudioBuffer; } // namespace bell namespace cspot { -class SpircHandler; +class DeviceStateHandler; } // namespace cspot class CliPlayer : public bell::Task { public: CliPlayer(std::unique_ptr sink, - std::shared_ptr spircHandler); + std::shared_ptr handler); void disconnect(); private: std::string currentTrackId; - std::shared_ptr handler; + std::shared_ptr handler; std::shared_ptr dsp; std::unique_ptr audioSink; std::shared_ptr centralAudioBuffer; + std::deque> tracks = {}; void feedData(uint8_t* data, size_t len); diff --git a/targets/cli/main.cpp b/targets/cli/main.cpp index a4249875..536d959b 100644 --- a/targets/cli/main.cpp +++ b/targets/cli/main.cpp @@ -1,18 +1,18 @@ -#include // for __base, function +#include +#include // for __base, function +#include #include // for operator!=, map, map<>::mapped_type +#include // for std::osstringstream #include // for invalid_argument #include // for remove_extent_t #include // for vector -#include -#include -#include // for std::osstringstream #include "BellHTTPServer.h" // for BellHTTPServer #include "BellLogger.h" // for setDefaultLogger, AbstractLogger #include "CSpotContext.h" // for Context, Context::ConfigState #include "CliPlayer.h" // for CliPlayer +#include "DeviceStateHandler.h" // for DeviceStateHandler #include "MDNSService.h" // for MDNSService -#include "SpircHandler.h" // for SpircHandler #include "WrappedSemaphore.h" // for WrappedSemaphore #include "civetweb.h" // for mg_header, mg_get_request_info #include "nlohmann/json.hpp" // for basic_json<>::object_t, basic_json @@ -151,7 +151,8 @@ int main(int argc, char** argv) { std::cout << "-p, --password your spotify password, note that " "if you use facebook login you can set a password in your " "account settings\n"; - std::cout << "-c, --credentials json file to store/load reusable credentials\n"; + std::cout << "-c, --credentials json file to store/load reusable " + "credentials\n"; std::cout << "-b, --bitrate bitrate (320, 160, 96)\n"; std::cout << "\n"; std::cout << "ddd 2022\n"; @@ -168,11 +169,11 @@ int main(int argc, char** argv) { } // reusable credentials else if (!args->credentials.empty()) { - std::ifstream file(args->credentials); - std::ostringstream credentials; - credentials << file.rdbuf(); - loginBlob->loadJson(credentials.str()); - loggedInSemaphore->give(); + std::ifstream file(args->credentials); + std::ostringstream credentials; + credentials << file.rdbuf(); + loginBlob->loadJson(credentials.str()); + loggedInSemaphore->give(); } // ZeroconfAuthenticator else { @@ -200,12 +201,12 @@ int main(int argc, char** argv) { if (ctx->config.authData.size() > 0) { // when credentials file is set, then store reusable credentials if (!args->credentials.empty()) { - std::ofstream file(args->credentials); - file << ctx->getCredentialsJson(); + std::ofstream file(args->credentials); + file << ctx->getCredentialsJson(); } - // Start spirc task - auto handler = std::make_shared(ctx); + // Start DeviceStateHandler + auto handler = std::make_shared(ctx); // Start handling mercury messages ctx->session->startTask(); diff --git a/targets/esp32/components/VS1053/CMakeLists.txt b/targets/esp32/components/VS1053/CMakeLists.txt new file mode 100644 index 00000000..2d42d503 --- /dev/null +++ b/targets/esp32/components/VS1053/CMakeLists.txt @@ -0,0 +1,4 @@ +set(CMAKE_CXX_STANDARD 17) + idf_component_register(SRCS "src/VS1053.cpp" INCLUDE_DIRS + "include" + "src" PRIV_REQUIRES fatfs) diff --git a/targets/esp32/components/VS1053/Kconfig b/targets/esp32/components/VS1053/Kconfig new file mode 100644 index 00000000..9b45b46c --- /dev/null +++ b/targets/esp32/components/VS1053/Kconfig @@ -0,0 +1,69 @@ +menu "VS1053 Configuration" + + menu "VS1053 PIN Configuration" + + config GPIO_MISO + int "GPIO pin MISO" + range -1 39 + default 19 + + config GPIO_MOSI + int "GPIO pin MOSI" + range -1 39 + default 23 + + config GPIO_CLK + int "GPIO pin CLK" + range -1 39 + default 18 + + config GPIO_VS_CS + int "GPIO pin VS CS" + range -1 39 + default 4 + + config GPIO_VS_DCS + int "GPIO pin VS DCS" + range -1 39 + default 21 + + config GPIO_VS_RESET + int "GPIO pin VS RESET" + range -1 39 + default 0 + + config GPIO_VS_DREQ + int "GPIO pin VS DREQ" + range -1 39 + default 22 + + config GPIO_SD_CS + int "GPIO pin SD CS" + range -1 39 + default 5 + endmenu + +choice VS_PLUGIN + prompt "VS1053 plugin" + default VS_FLAC + help + you have to choose between special audio compability or a spectrum analyzer + config VS_DSD64 + bool "with dsd patch" + config VS_FLAC + bool "with flac patch" + config VS_FLAC_LATM + bool "with flac & latm/loas patch" + config VS_LATM + bool "with latm/loas patch" + config VS_PITCH + bool "with pitch plugin" + config VS_SPECTRUM_ANALYZER + bool "with spectrum analyzer plugin" +endchoice + + +config REPORT_ON_SCREEN + bool "REPORT_ON_SCREEN" + +endmenu diff --git a/targets/esp32/components/VS1053/component.mk b/targets/esp32/components/VS1053/component.mk new file mode 100644 index 00000000..e69de29b diff --git a/targets/esp32/components/VS1053/include/VS1053.h b/targets/esp32/components/VS1053/include/VS1053.h new file mode 100644 index 00000000..78acd468 --- /dev/null +++ b/targets/esp32/components/VS1053/include/VS1053.h @@ -0,0 +1,240 @@ +#ifndef VS1053_H +#define VS1053_H + +#include //for memset +#include //for dequeue +#include //for function +#include +#include + +#include "esp_err.h" + +#include +#include + +#include "freertos/semphr.h" +#include "freertos/stream_buffer.h" +#include "freertos/task.h" + +#include "vs10xx_uc.h" +#ifdef CONFIG_VS_DSD64 +#include "patches_dsd.h" +#endif +#ifdef CONFIG_VS_FLAC +#include "patches_flac.h" +#endif +#ifdef CONFIG_VS_FLAC_LATM +#include "patches_flac_latm.h" +#endif +#ifdef CONFIG_VS_LATM +#include "patches_latm.h" +#endif +#ifdef CONFIG_VS_PITCH +#include "patches_pitch.h" +#endif +#ifdef CONFIG_VS_SPECTRUM_ANALYZER +#include "spectrum_analyzer.h" +#endif + +#define VERSION 1 +#define VS1053_CHUNK_SIZE 16 // chunck size +#define VS1053_PACKET_SIZE 8 +#define BUF_SIZE_CMD 1028 +#define BUF_SIZE_FEED 4096 * 4 + +#define SDI_END_FILL_BYTES_FLAC 12288 +#define SDI_END_FILL_BYTES 2050 + +#define REPORT_INTERVAL 4096 +#define REPORT_INTERVAL_MIDI 512 +/** + * + * callback for the command_pipeline + * + */ +class VS1053_SINK; +class VS1053_TRACK { + public: + VS1053_TRACK(size_t track_id = 0, size_t buffer_size = BUF_SIZE_FEED); + ~VS1053_TRACK(); + /** + * feed data to dataBuffer + * @param data pointer to byte array + * @param len length of the byte array + * @warning always call data_request, before feeding data, + * to get available space in dataBuffer + */ + size_t feed_data(uint8_t* data, size_t len, bool STORAGE_VOLATILE = 0); + void empty_feed(); + void run_track(size_t FILL_BUFFER_BEFORE_PLAYSTART = 0); + enum VS_TRACK_STATE { + tsPlaybackStart = 0, + tsPlayback = 1, + tsPlaybackSeekable = 2, + tsPlaybackPaused = 3, + tsSoftCancel = 4, + tsCancel = 5, + tsCancelAwait = 6, + tsStopped = 7 + } state = tsPlaybackStart; + size_t header_size = 0; + size_t track_id; + StreamBufferHandle_t dataBuffer; + + private: +}; +class VS1053_SINK { + public: + /** + * `CONSTRUCTOR` + * + * PULLS CS and DCS HIGH. + * If RESET >= 0, VS1053 gets hardreset. + * For sharing the SPI_BUS with a SD-Card, the CS-pins + * of the other devices are needed to be pulled high + * before mounting the SD-card. + * After mounting the SD-card, you can add the other devices + * + * @param RESET GPIO_PIN_NUM, if + */ + VS1053_SINK(); + + /** + * DECONSTRUCTOR + */ + ~VS1053_SINK(); + typedef std::function command_callback; + //typedef std::function command_callback; + /** + * `init feed` + * add the VS 1053 to the SPI_BUS, test the device and + * add vs_loop to freertosTask + * + * @param SPI pointer to the used SPI peripheral + * @param SPI_semaphore semaphore for the SPI_BUS, NULL if uninitiallized + * + * @return `ESP_OK` if setup worked. + * @return `ESP_ERR_INVALID_RESPONSE` if the register response is wrong. + * @return `ESP_ERR_NOT_SUPPORTED` if the chip is not a VS1053. + * @return `ESP_ERR_NOT_FOUND` if the chipNumber is not recognized. + */ + esp_err_t init(spi_host_device_t SPI, + SemaphoreHandle_t* SPI_semaphore = NULL); + /** + * stops data feed imeaditly + */ + void stop_feed(); + /** + * stops data feed if dataBuffer contains no more + */ + void soft_stop_feed(); + /** + * feed data to commandBuffer + * @param command_callback callback function + * + */ + uint8_t feed_command(command_callback commandCallback); + void set_volume_logarithmic(size_t vol); + /** + * set volume through cmd_pipeline, sets left and right volume to vol + * @param vol 0...100, gets capped if bigger + */ + void set_volume(uint8_t vol); + /** + * set volume through cmd_pipeline, sets separate volume for left and right channel + * @param left 0...100, gets capped if bigger + * @param right 0...100, gets capped if bigger + */ + void set_volume(uint8_t left, uint8_t right); + /** + * get available Space in dataBuffer + * @return free space available in dataBuffer + */ + size_t data_request(std::shared_ptr track); + /** + * loads Usercode(PATCH) + * @param plugin uint8_t * to plugin array + * @param sizeofpatch length of the array + */ + void load_user_code(const unsigned short* plugin, uint16_t sizeofpatch); + /** + * test SPI communication and if the board is a VS1053 + * @return `ESP_OK` if setup worked. + * @return `ESP_ERR_INVALID_RESPONSE` if the register response is wrong. + * @return `ESP_ERR_NOT_SUPPORTED` if the chip is not a VS1053. + * @return `ESP_ERR_NOT_FOUND` if the chipNumber is not recognized. + */ + esp_err_t test_comm(const char* header); + + void run_feed(size_t); + + std::function state_callback = nullptr; + enum Audio_Format { + afUnknown, + afRiff, + afOggVorbis, + afMp1, + afMp2, + afMp3, + afAacMp4, + afAacAdts, + afAacAdif, + afFlac, + afWma, + afMidi, + afDsd64, + afLatm + } audioFormat = afUnknown; + + std::deque command_callbacks; + std::deque> tracks; + + void get_audio_format(Audio_Format* audioFormat, size_t* endFillBytes); + void control_mode_on(); + void control_mode_off(); + void data_mode_on(); + void data_mode_off(); + uint16_t read_register(uint8_t _reg); + bool write_register(uint8_t _reg, uint16_t _value); + uint32_t read_mem32(uint16_t addr); + uint32_t read_mem32_counter(uint16_t addr); + uint16_t read_mem(uint16_t addr); + void write_mem(uint16_t addr, uint16_t data); + void write_mem32(uint16_t addr, uint32_t data); + bool sdi_send_buffer(uint8_t* data, size_t len); + void remove_track(std::shared_ptr track) { + for (int i = 0; i < tracks.size(); i++) + if (tracks[i]->track_id == track->track_id) + tracks.erase(tracks.begin() + i); + }; + void start_track(std::shared_ptr, size_t); + size_t track_seekable(size_t); + void cancel_track(VS1053_TRACK::VS_TRACK_STATE* state); + bool is_cancelled(VS1053_TRACK::VS_TRACK_STATE* state, uint8_t, size_t); + size_t get_track_info(size_t, uint8_t&, size_t&); + void new_state(VS1053_TRACK::VS_TRACK_STATE&, VS1053_TRACK::VS_TRACK_STATE); + void new_track(std::shared_ptr track); + + void delete_all_tracks(void); + size_t spaces_available(size_t); + size_t command_pointer = 0, command_reader = 0; + bool isRunning = false; + + private: + spi_device_handle_t SPIHandleLow; + spi_device_handle_t SPIHandleFast; + uint8_t curvol; // Current volume setting 0..100% + int playMode = 0; + uint8_t chipVersion; // Version of hardware + SemaphoreHandle_t* SPI_semaphore = NULL; + TaskHandle_t VS_TASK; + void await_data_request(); + bool is_seekable(VS1053_TRACK::VS_TRACK_STATE* state); + bool sdi_send_fillers(uint8_t, size_t len); + void wram_write(uint16_t address, uint16_t data); + uint16_t wram_read(uint16_t address); + size_t (*data_callback)(uint8_t*, size_t) = NULL; + TaskHandle_t task_handle = NULL; +}; + +#endif \ No newline at end of file diff --git a/targets/esp32/components/VS1053/include/patches_dsd.h b/targets/esp32/components/VS1053/include/patches_dsd.h new file mode 100644 index 00000000..d9ac29d9 --- /dev/null +++ b/targets/esp32/components/VS1053/include/patches_dsd.h @@ -0,0 +1,983 @@ + +#ifndef SKIP_PLUGIN_VARNAME +const unsigned short PLUGIN[] = { + /* Compressed plugin */ +#endif + 0x0007, 0x0001, /*copy 1*/ + 0x8050, 0x0006, 0x001e, /*copy 30*/ + 0x2a00, 0xc000, 0x3e12, 0xb817, 0x3e14, 0xf812, 0x3e01, 0xb811, 0x0007, + 0x9717, 0x0020, 0xffd2, 0x0030, 0x11d1, 0x3111, 0x8024, 0x3704, 0xc024, + 0x3b81, 0x8024, 0x3101, 0x8024, 0x3b81, 0x8024, 0x3f04, 0xc024, 0x2808, + 0x4800, 0x36f1, 0x9811, 0x0007, 0x0001, /*copy 1*/ + 0x8060, 0x0006, 0x053e, /*copy 1342*/ + 0xf400, 0x4095, 0x0000, 0x02c2, 0x6124, 0x0024, 0x0000, 0x0024, 0x2800, + 0x1ac5, 0x4192, 0x4542, 0x0000, 0x0041, 0x2000, 0x0015, 0x0030, 0x0317, + 0x2000, 0x0000, 0x3f00, 0x4024, 0x2000, 0x0000, 0x0000, 0x0000, 0x3e12, + 0x3800, 0x3e00, 0xb804, 0x0030, 0x0015, 0x0007, 0x8257, 0x3700, 0x984c, + 0xf224, 0x1444, 0xf224, 0x0024, 0x0008, 0x0002, 0x2910, 0x0181, 0x0000, + 0x1bc8, 0xb428, 0x1402, 0x0000, 0x8004, 0x2910, 0x0195, 0x0000, 0x1bc8, + 0xb428, 0x0024, 0x0006, 0x0095, 0x2800, 0x2945, 0x3e13, 0x780e, 0x3e11, + 0x7803, 0x3e13, 0xf806, 0x3e11, 0xf801, 0x3510, 0xb808, 0x003f, 0xe004, + 0xfec4, 0x3800, 0x48be, 0x17c3, 0xfec6, 0x41c2, 0x48be, 0x4497, 0x4090, + 0x1c46, 0xf06c, 0x0024, 0x2400, 0x2580, 0x6090, 0x41c3, 0x6628, 0x1c47, + 0x0000, 0x0024, 0x2800, 0x2449, 0xf07e, 0x0024, 0xf400, 0x4182, 0x673a, + 0x1c46, 0x0000, 0x0024, 0x2800, 0x2589, 0xf06c, 0x0024, 0xf400, 0x41c3, + 0x0000, 0x0024, 0x4224, 0x3442, 0x2903, 0xdc80, 0x4336, 0x37c3, 0x0000, + 0x1805, 0x2903, 0xdc80, 0x4508, 0x40c2, 0x450a, 0x9808, 0x0000, 0x0207, + 0xa478, 0x1bc0, 0xc45a, 0x1807, 0x0030, 0x03d5, 0x3d01, 0x5bc1, 0x36f3, + 0xd806, 0x3601, 0x5803, 0x36f3, 0x0024, 0x36f3, 0x580e, 0x0007, 0x8257, + 0x0000, 0x6004, 0x3730, 0x8024, 0xb244, 0x1c04, 0xd428, 0x3c02, 0x0006, + 0xc717, 0x2800, 0x2d05, 0x4284, 0x0024, 0x3613, 0x3c02, 0x0006, 0xc357, + 0x2901, 0x6a00, 0x3e11, 0x5c05, 0x4284, 0x1bc5, 0x0007, 0x8257, 0x2800, + 0x3285, 0x0002, 0x0001, 0x3701, 0x0024, 0x0006, 0xc357, 0xb412, 0x9c02, + 0x002e, 0xe001, 0x2800, 0x3005, 0x6212, 0x0024, 0x0000, 0x0024, 0x2800, + 0x3295, 0x0000, 0x0024, 0x0030, 0x0117, 0x3f00, 0x0024, 0x3613, 0x0024, + 0x3e10, 0x3813, 0x3e14, 0x8024, 0x3e04, 0x8024, 0x2900, 0x4b40, 0x0006, + 0x02d3, 0x36e3, 0x0024, 0x3009, 0x1bd3, 0x0007, 0x8257, 0x3700, 0x8024, + 0xf224, 0x0024, 0x0000, 0x0024, 0x2800, 0x3491, 0x3600, 0x9844, 0x2900, + 0x3a40, 0x0000, 0x3508, 0x2911, 0xf140, 0x0000, 0x0024, 0x0030, 0x0057, + 0x3700, 0x0024, 0xf200, 0x4595, 0x0fff, 0xfe02, 0xa024, 0x164c, 0x8000, + 0x17cc, 0x3f00, 0x0024, 0x3500, 0x0024, 0x0021, 0x6d82, 0xd024, 0x44c0, + 0x0006, 0xa402, 0x2800, 0x3955, 0xd024, 0x0024, 0x0000, 0x0000, 0x2800, + 0x3955, 0x000b, 0x6d57, 0x3009, 0x3c00, 0x36f0, 0x8024, 0x36f2, 0x1800, + 0x2000, 0x0000, 0x0000, 0x0024, 0x3e14, 0x7810, 0x3e13, 0xb80d, 0x3e13, + 0xf80a, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0xf801, + 0x3e15, 0x3815, 0x0001, 0x000a, 0x0006, 0xc4d7, 0xbf8e, 0x9c42, 0x3e01, + 0x9c03, 0x0006, 0xa017, 0x0023, 0xffd1, 0x0007, 0x8250, 0x0fff, 0xfd85, + 0x3001, 0x0024, 0xa45a, 0x4494, 0x0000, 0x0093, 0x2800, 0x4091, 0xf25a, + 0x104c, 0x34f3, 0x0024, 0x2800, 0x4091, 0x0000, 0x0024, 0x3413, 0x084c, + 0x0000, 0x0095, 0x3281, 0xf806, 0x4091, 0x4d64, 0x2400, 0x42c0, 0x4efa, + 0x9c10, 0xf1eb, 0x6061, 0xfe55, 0x2f66, 0x5653, 0x4d64, 0x48b2, 0xa201, + 0x4efa, 0xa201, 0x36f3, 0x3c10, 0x36f5, 0x1815, 0x36f4, 0xd801, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0xd80a, 0x36f3, 0x980d, + 0x2000, 0x0000, 0x36f4, 0x5810, 0x36f3, 0x0024, 0x3009, 0x3848, 0x3e14, + 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, 0x2915, 0x94c0, + 0x0001, 0xcc11, 0x36f0, 0x0024, 0x2927, 0x9e40, 0x3604, 0x1811, 0x3613, + 0x0024, 0x3e14, 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, + 0x2915, 0x94c0, 0x0001, 0xcc11, 0x36f0, 0x0024, 0x36f4, 0x1811, 0x3009, + 0x1808, 0x2000, 0x0000, 0x0000, 0x190d, 0x3613, 0x0024, 0x3e22, 0xb815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e13, 0x7801, 0x3e10, + 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x3e14, 0xb813, + 0x3e03, 0xf80e, 0xb488, 0x44d5, 0x3543, 0x134c, 0x34e5, 0xc024, 0x3524, + 0x8024, 0x35a4, 0xc024, 0x3710, 0x8a0c, 0x3540, 0x4a0c, 0x3d44, 0x8024, + 0x3a10, 0x8024, 0x3590, 0x0024, 0x4010, 0x15c1, 0x6010, 0x3400, 0x3710, + 0x8024, 0x2800, 0x5704, 0x3af0, 0x8024, 0x3df0, 0x0024, 0x3591, 0x4024, + 0x3530, 0x4024, 0x4192, 0x4050, 0x6100, 0x1482, 0x4020, 0x1753, 0xbf8e, + 0x1582, 0x4294, 0x4011, 0xbd86, 0x408e, 0x2400, 0x550e, 0xfe6d, 0x2819, + 0x520e, 0x0a00, 0x5207, 0x2819, 0x4fbe, 0x0024, 0xad56, 0x904c, 0xaf5e, + 0x1010, 0xf7d4, 0x0024, 0xf7fc, 0x2042, 0x6498, 0x2046, 0x3cf4, 0x0024, + 0x3400, 0x170c, 0x4090, 0x1492, 0x35a4, 0xc024, 0x2800, 0x4f95, 0x3c00, + 0x0024, 0x4480, 0x914c, 0x36f3, 0xd80e, 0x36f4, 0x9813, 0x36f4, 0x1811, + 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0x5801, 0x3405, + 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x0000, 0x0200, + 0xb386, 0x3803, 0xad06, 0x0024, 0x2000, 0x0000, 0xc320, 0x1bc3, 0x2814, + 0x9c91, 0x0000, 0x004d, 0x2814, 0x9940, 0x003f, 0x0013, 0x3e12, 0xb817, + 0x3e12, 0x7808, 0x3e11, 0xb811, 0x3e15, 0x7810, 0x3e18, 0xb823, 0x3e18, + 0x3821, 0x3e10, 0x3801, 0x48b2, 0x0024, 0x3e10, 0x3801, 0x3e11, 0x3802, + 0x3009, 0x3814, 0x0030, 0x0717, 0x3f05, 0xc024, 0x0030, 0x0351, 0x3100, + 0x0024, 0x4080, 0x0024, 0x0030, 0x10d1, 0x2800, 0x6885, 0x0001, 0x800a, + 0x0006, 0x6514, 0x3111, 0x8024, 0x6894, 0x13c1, 0x6618, 0x0024, 0xfe44, + 0x1000, 0x4cb2, 0x0406, 0x3c10, 0x0024, 0x3c50, 0x4024, 0x34f0, 0x4024, + 0x661c, 0x1040, 0xfe64, 0x0024, 0x4cb2, 0x0024, 0x3cf0, 0x4024, 0xbc82, + 0x3080, 0x0030, 0x0351, 0x3100, 0x8024, 0xfea8, 0x0024, 0x5ca2, 0x0024, + 0x0000, 0x0182, 0xac22, 0x0024, 0xf7c8, 0x0024, 0x48b2, 0x0024, 0xac22, + 0x0024, 0x2800, 0x6c00, 0xf7cc, 0x1002, 0x0030, 0x0394, 0x3400, 0x4024, + 0x3100, 0x184c, 0x0006, 0xc051, 0x291e, 0x8080, 0x0006, 0x6410, 0x4088, + 0x1001, 0x0030, 0x1111, 0x3100, 0x184c, 0x0006, 0xc051, 0x291e, 0x8080, + 0x0006, 0x6550, 0x0006, 0x6694, 0x408c, 0x1002, 0xf224, 0x0024, 0x0006, + 0xa017, 0x2800, 0x7015, 0x0000, 0x0024, 0x2808, 0x3f41, 0x0006, 0x6410, + 0x3050, 0x0024, 0x3000, 0x4024, 0x6014, 0x0024, 0x0000, 0x0024, 0x2800, + 0x6f59, 0x0000, 0x0024, 0xf400, 0x4040, 0x38b0, 0x0024, 0x2808, 0x3f40, + 0x3800, 0x0024, 0x2800, 0x7201, 0xf224, 0x0024, 0x0000, 0x0024, 0x2808, + 0x3f45, 0x4684, 0x4106, 0xf12c, 0x0024, 0xf148, 0x0024, 0x846c, 0x0024, + 0x2808, 0x3f40, 0xf400, 0x4184, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x3625, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, + 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x0006, 0xa090, 0x2912, + 0x0d00, 0x3e14, 0xc024, 0x4088, 0x8000, 0x4080, 0x0024, 0x0007, 0x90d1, + 0x2800, 0x7845, 0x0000, 0x0024, 0x0007, 0x9051, 0x3100, 0x4024, 0x4100, + 0x0024, 0x3900, 0x0024, 0x0007, 0x90d1, 0x0004, 0x0000, 0x31f0, 0x4024, + 0x6014, 0x0400, 0x0000, 0x0024, 0x2800, 0x7c91, 0x4080, 0x0024, 0x0000, + 0x0000, 0x2800, 0x7c05, 0x0000, 0x0024, 0x0007, 0x9053, 0x3300, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0000, 0x2800, 0x7c98, 0x0000, 0x0024, 0x0007, + 0x9051, 0x3900, 0x0024, 0x3200, 0x504c, 0x6410, 0x0024, 0x3cf0, 0x0000, + 0x4080, 0x0024, 0x0006, 0xc691, 0x2800, 0x9545, 0x3009, 0x0400, 0x0000, + 0x1001, 0x0007, 0x9051, 0x3100, 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, + 0x2800, 0x8989, 0x003f, 0xe000, 0x0006, 0xc693, 0x3900, 0x0c00, 0x3009, + 0x0001, 0x6014, 0x0024, 0x0007, 0x1ad0, 0x2800, 0x8995, 0x3009, 0x0000, + 0x4080, 0x0024, 0x0000, 0x0301, 0x2800, 0x8385, 0x4090, 0x0024, 0x0000, + 0x0024, 0x2800, 0x8495, 0x0000, 0x0024, 0x3009, 0x0000, 0xc012, 0x0024, + 0x2800, 0x8980, 0x3009, 0x2001, 0x3009, 0x0000, 0x6012, 0x0024, 0x0000, + 0x0341, 0x2800, 0x8695, 0x0000, 0x0024, 0x6190, 0x0024, 0x2800, 0x8980, + 0x3009, 0x2000, 0x6012, 0x0024, 0x0000, 0x0381, 0x2800, 0x8855, 0x0000, + 0x0024, 0x6190, 0x0024, 0x2800, 0x8980, 0x3009, 0x2000, 0x6012, 0x0024, + 0x0000, 0x00c0, 0x2800, 0x8995, 0x0000, 0x0024, 0x3009, 0x2000, 0x0006, + 0xa090, 0x3009, 0x0000, 0x4080, 0x0024, 0x0000, 0x0081, 0x2800, 0x8e55, + 0x0007, 0x8c13, 0x3300, 0x104c, 0xb010, 0x0024, 0x0002, 0x8001, 0x2800, + 0x90c5, 0x34f0, 0x0024, 0x2800, 0x8e40, 0x0000, 0x0024, 0x0006, 0xc351, + 0x3009, 0x0000, 0x6090, 0x0024, 0x3009, 0x2000, 0x2900, 0x0b80, 0x3009, + 0x0405, 0x0006, 0xc6d1, 0x0006, 0xc690, 0x3009, 0x0000, 0x3009, 0x0401, + 0x6014, 0x0024, 0x0006, 0xa093, 0x2800, 0x8cd1, 0xb880, 0x0024, 0x2800, + 0x9e00, 0x3009, 0x2c00, 0x4040, 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, + 0x2800, 0x9e18, 0x0000, 0x0024, 0x0006, 0xc693, 0x3009, 0x0c00, 0x3009, + 0x0001, 0x6014, 0x0024, 0x0006, 0xc350, 0x2800, 0x9e01, 0x0000, 0x0024, + 0x6090, 0x0024, 0x3009, 0x2c00, 0x3009, 0x0005, 0x2900, 0x0b80, 0x0000, + 0x9e08, 0x3009, 0x0400, 0x4080, 0x0024, 0x0003, 0x8000, 0x2800, 0x9e05, + 0x0000, 0x0024, 0x6400, 0x0024, 0x0000, 0x0081, 0x2800, 0x9e09, 0x0000, + 0x0024, 0x0007, 0x8c13, 0x3300, 0x0024, 0xb010, 0x0024, 0x0006, 0xc650, + 0x2800, 0x9e15, 0x0000, 0x0024, 0x0001, 0x0002, 0x3413, 0x0000, 0x3009, + 0x0401, 0x4010, 0x8406, 0x0000, 0x0281, 0xa010, 0x13c1, 0x4122, 0x0024, + 0x0000, 0x03c2, 0x6122, 0x8002, 0x462c, 0x0024, 0x469c, 0x0024, 0xfee2, + 0x0024, 0x48be, 0x0024, 0x6066, 0x8400, 0x0006, 0xc350, 0x2800, 0x9e01, + 0x0000, 0x0024, 0x4090, 0x0024, 0x3009, 0x2400, 0x2900, 0x0b80, 0x3009, + 0x0005, 0x0007, 0x1b50, 0x2912, 0x0d00, 0x3613, 0x0024, 0x3a00, 0x0380, + 0x4080, 0x0024, 0x0000, 0x00c1, 0x2800, 0xa6c5, 0x3009, 0x0000, 0xb010, + 0x008c, 0x4192, 0x0024, 0x6012, 0x0024, 0x0006, 0xf051, 0x2800, 0xa4d8, + 0x3009, 0x0400, 0x0007, 0x1fd1, 0x30e3, 0x0400, 0x4080, 0x0024, 0x0000, + 0x0301, 0x2800, 0xa6c5, 0x3009, 0x0000, 0xb010, 0x0024, 0x0000, 0x0101, + 0x6012, 0x0024, 0x0006, 0xf051, 0x2800, 0xa6d5, 0x0000, 0x0024, 0x3023, + 0x0400, 0xf200, 0x184c, 0xb880, 0xa400, 0x3009, 0x2000, 0x3009, 0x0441, + 0x3e10, 0x4402, 0x2909, 0xa9c0, 0x3e10, 0x8024, 0x36e3, 0x0024, 0x36f4, + 0xc024, 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x3e11, + 0x3805, 0x3e14, 0x3811, 0x3e14, 0x92cc, 0x3400, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0590, 0x2800, 0xb058, 0x0000, 0x0024, 0x6800, 0x9bcc, 0x3c20, + 0x0024, 0x34e4, 0x4024, 0x3410, 0x860c, 0x3100, 0x0024, 0xff20, 0x1012, + 0x48b6, 0x084c, 0x4280, 0x1110, 0x6898, 0x0024, 0x2900, 0xb480, 0x0000, + 0x0085, 0x34b3, 0x184c, 0x3410, 0x0024, 0x3e10, 0x0024, 0x3410, 0x0024, + 0x3e10, 0x0024, 0x3430, 0x0024, 0x2920, 0x1340, 0x3e00, 0x0024, 0x36d3, + 0x0024, 0x36f4, 0x8024, 0x36f4, 0x1811, 0x36f1, 0x1805, 0x36f0, 0x9803, + 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, + 0x9817, 0x4090, 0x184c, 0x3e14, 0xf811, 0x3e13, 0xf80e, 0x2800, 0xb6c4, + 0x3e03, 0x4024, 0x2400, 0xb680, 0x2b11, 0x1153, 0x3280, 0x0024, 0x3880, + 0x0024, 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x36f4, 0xd811, + 0x4090, 0x184c, 0x3e14, 0xf811, 0x3e13, 0xf80e, 0x2800, 0xbac4, 0x4498, + 0x380d, 0x459a, 0x0024, 0x2400, 0xba80, 0x2b11, 0x1153, 0x3210, 0x0024, + 0x3810, 0x0024, 0x3280, 0x0024, 0x3880, 0x0024, 0x36f3, 0x4024, 0x36f3, + 0xd80e, 0x2000, 0x0000, 0x36f4, 0xd811, 0x3613, 0x0024, 0x3e22, 0xb815, + 0x3e05, 0xb814, 0xb880, 0x1854, 0x3405, 0x9014, 0x36e3, 0x0024, 0x2000, + 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, + 0x3615, 0x0024, 0x3405, 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, + 0x9815, 0x0007, 0x0001, /*copy 1*/ + 0x8300, 0x0006, 0x191c, /*copy 6428*/ + 0x0030, 0x0055, 0xb080, 0x1402, 0x0fdf, 0xffc1, 0x0007, 0x9257, 0xb212, + 0x3c00, 0x3d00, 0x4024, 0x0006, 0x0097, 0x3f10, 0x0024, 0x3f00, 0x0024, + 0x0030, 0x0297, 0x3f00, 0x0024, 0x0007, 0x9017, 0x3f00, 0x0024, 0x0007, + 0x81d7, 0x3f10, 0x0024, 0xc090, 0x3c00, 0x0006, 0x0297, 0xb080, 0x3c00, + 0x0000, 0x0401, 0x000a, 0x1055, 0x0006, 0x0017, 0x3f10, 0x3401, 0x000a, + 0x2795, 0x3f00, 0x3401, 0x0001, 0x69d7, 0xf400, 0x55c0, 0x0000, 0x0817, + 0xb080, 0x57c0, 0x0014, 0x958f, 0x0000, 0x5c8e, 0x0030, 0x0017, 0x3700, + 0x0024, 0x0004, 0x0001, 0xb012, 0x0024, 0x0000, 0x004d, 0x280f, 0xe115, + 0x0006, 0x2016, 0x0006, 0x01d7, 0x3f00, 0x0024, 0x0000, 0x190d, 0x000f, + 0xf94f, 0x0000, 0xcd0e, 0x280f, 0xe100, 0x0006, 0x2016, 0x0000, 0x0080, + 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, + 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0007, 0x8a57, 0x3700, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0040, 0x2800, 0xced5, 0x0006, 0xa2d7, 0x3009, + 0x3c00, 0x0006, 0xa157, 0x3009, 0x1c00, 0x0006, 0x01d7, 0x0000, 0x190d, + 0x000a, 0x708f, 0x0000, 0xd7ce, 0x290b, 0x1a80, 0x3f00, 0x184c, 0x0030, + 0x0017, 0x4080, 0x1c01, 0x0000, 0x0200, 0x2800, 0xcb15, 0xb102, 0x0024, + 0x0000, 0xcd08, 0x2800, 0xcb15, 0x0000, 0xd3ce, 0x0011, 0x210f, 0x0000, + 0x190d, 0x280f, 0xcb00, 0x3613, 0x0024, 0x0006, 0xa115, 0x0006, 0x01d7, + 0x37f0, 0x1401, 0x6100, 0x1c01, 0x4012, 0x0024, 0x0000, 0x8000, 0x6010, + 0x0024, 0x34f3, 0x0400, 0x2800, 0xd698, 0x0000, 0x0024, 0x0000, 0x8001, + 0x6010, 0x3c01, 0x0000, 0x000d, 0x2811, 0x8259, 0x0000, 0x0024, 0x2a11, + 0x2100, 0x0030, 0x0257, 0x3700, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2800, 0xd9d5, 0x0006, 0x0197, 0x0006, 0xa115, 0x3f00, 0x3400, 0x4d86, + 0x0024, 0x0000, 0x190d, 0x2800, 0xdd55, 0x0014, 0x1b01, 0x0020, 0x480f, + 0x0000, 0xdc0e, 0x0000, 0x190d, 0x2820, 0x41c0, 0x0001, 0x10c8, 0x0039, + 0x324f, 0x0001, 0x3dce, 0x2820, 0x4a18, 0xb882, 0x0024, 0x2a20, 0x48c0, + 0x003f, 0xfd00, 0xb700, 0x0024, 0x003f, 0xf901, 0x6010, 0x0024, 0x0000, + 0x0024, 0x280a, 0xc505, 0x0000, 0x190d, 0x0014, 0x1b01, 0x0015, 0x59c0, + 0x6fc2, 0x0024, 0x0000, 0x0024, 0x2800, 0xe795, 0x0000, 0x0024, 0x290c, + 0x4840, 0x3613, 0x0024, 0x290c, 0x4840, 0x4086, 0x184c, 0x0000, 0x18c2, + 0x6234, 0x0024, 0x0000, 0x1d02, 0x2800, 0xe395, 0x6234, 0x0024, 0x0030, + 0x0317, 0x2800, 0xe780, 0x3f00, 0x0024, 0x0000, 0x1d82, 0x2800, 0xe615, + 0x6234, 0x0024, 0x2912, 0x0d00, 0x4084, 0x184c, 0xf200, 0x0024, 0x6200, + 0x0024, 0x0006, 0x0017, 0x2800, 0xe300, 0xb080, 0x3c40, 0x0000, 0x0202, + 0x2800, 0xe795, 0xa024, 0x0024, 0xc020, 0x0024, 0x2800, 0xe300, 0x0030, + 0x02d7, 0x0011, 0x14c1, 0x0011, 0x0800, 0x6fc2, 0x0024, 0x0011, 0x9481, + 0x2800, 0xea05, 0x0013, 0x4e00, 0x6fc2, 0x0024, 0x0000, 0x0024, 0x2800, + 0xea95, 0x0000, 0x0024, 0x2801, 0x8ec0, 0x000a, 0xcac8, 0x000a, 0x8c8f, + 0x0000, 0xebce, 0x000c, 0x0981, 0x280a, 0x71c0, 0x002c, 0x9d40, 0x000a, + 0x708f, 0x0000, 0xd7ce, 0x280a, 0xc0d5, 0x0012, 0x5182, 0x6fd6, 0x0024, + 0x003f, 0xfd81, 0x280a, 0x8e45, 0xb710, 0x0024, 0xb710, 0x0024, 0x003f, + 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, 0x0795, 0xffd2, 0x0024, + 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x190d, 0x2801, 0x0795, 0x0030, + 0x0250, 0xb880, 0x104c, 0x3cf0, 0x0024, 0x0010, 0x5500, 0xb880, 0x23c0, + 0xb882, 0x2000, 0x0007, 0x8590, 0x2914, 0xbec0, 0x0000, 0x0440, 0x0007, + 0x8b50, 0xb880, 0x0024, 0x2920, 0x0100, 0x3800, 0x0024, 0x2920, 0x0000, + 0x0006, 0x8a91, 0x0000, 0x0800, 0xb880, 0xa440, 0x003f, 0xfd81, 0xb710, + 0xa7c0, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, 0x10d5, + 0x0000, 0x0024, 0xffe2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, + 0x0024, 0x2801, 0x10d5, 0x0000, 0x0024, 0x2912, 0x2d80, 0x0000, 0x0780, + 0x4080, 0x0024, 0x0006, 0x8a90, 0x2801, 0x10d5, 0x0000, 0x01c2, 0xb886, + 0x8040, 0x3613, 0x03c1, 0xbcd2, 0x0024, 0x0030, 0x0011, 0x2800, 0xfd55, + 0x003f, 0xff42, 0xb886, 0x8040, 0x3009, 0x03c1, 0x0000, 0x0020, 0xac22, + 0x0024, 0x0000, 0x0102, 0x6cd2, 0x0024, 0x3e10, 0x0024, 0x2909, 0x8c80, + 0x3e00, 0x4024, 0x36f3, 0x0024, 0x3e11, 0x8024, 0x3e01, 0xc024, 0x2901, + 0x3480, 0x0000, 0x0201, 0xf400, 0x4512, 0x2900, 0x0c80, 0x3213, 0x1b8c, + 0x3100, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, 0x2801, 0x10d5, 0x0000, + 0x0024, 0x291a, 0x8a40, 0x0000, 0x0100, 0x2920, 0x0200, 0x3633, 0x0024, + 0x2920, 0x0280, 0x0000, 0x0401, 0x408e, 0x0024, 0x2920, 0x0280, 0x0000, + 0x0401, 0x003f, 0xfd81, 0xb710, 0x4006, 0x003f, 0xfc01, 0x6012, 0x0024, + 0x0000, 0x0101, 0x2801, 0x10d5, 0x0000, 0x0024, 0xffe2, 0x0024, 0x48b2, + 0x0024, 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, 0x10d5, 0x0000, 0x0024, + 0x2912, 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, 0x0000, 0x01c2, 0x2800, + 0xf945, 0x0006, 0x8a90, 0x2a01, 0x10c0, 0x2920, 0x0100, 0x0000, 0x0401, + 0x0000, 0x0180, 0x2920, 0x0200, 0x3613, 0x0024, 0x2920, 0x0280, 0x3613, + 0x0024, 0x0000, 0x0401, 0x2920, 0x0280, 0x4084, 0x984c, 0x0019, 0x9d01, + 0x6212, 0x0024, 0x001e, 0x5c01, 0x2801, 0x0c15, 0x6012, 0x0024, 0x0000, + 0x0024, 0x2801, 0x0e05, 0x0000, 0x0024, 0x001b, 0x5bc1, 0x6212, 0x0024, + 0x001b, 0xdd81, 0x2801, 0x11d5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, + 0x11d5, 0x0000, 0x0024, 0x0000, 0x004d, 0x000a, 0xbf4f, 0x280a, 0xb880, + 0x0001, 0x0f0e, 0x0020, 0xfb4f, 0x0000, 0x190d, 0x0001, 0x160e, 0x2920, + 0xf440, 0x3009, 0x2bc1, 0x291a, 0x8a40, 0x36e3, 0x0024, 0x0000, 0x190d, + 0x000a, 0x708f, 0x280a, 0xcac0, 0x0000, 0xd7ce, 0x0030, 0x0017, 0x3700, + 0x4024, 0x0000, 0x0200, 0xb102, 0x0024, 0x0000, 0x00c0, 0x2801, 0x1505, + 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, + 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0000, 0x190d, 0x000a, 0x708f, + 0x280a, 0xc0c0, 0x0000, 0xd7ce, 0x0000, 0x004d, 0x0020, 0xfe0f, 0x2820, + 0xfb40, 0x0001, 0x170e, 0x2801, 0x18d5, 0x3009, 0x1000, 0x6012, 0x93cc, + 0x0000, 0x0024, 0x2801, 0x3385, 0x0000, 0x0024, 0x3413, 0x0024, 0x34b0, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0200, 0x2801, 0x1bd5, 0xb882, 0x0024, + 0x3453, 0x0024, 0x3009, 0x13c0, 0x4080, 0x0024, 0x0000, 0x0200, 0x2801, + 0x3385, 0x0000, 0x0024, 0xb882, 0x130c, 0x0000, 0x004d, 0x0021, 0x058f, + 0x2821, 0x0340, 0x0001, 0x1cce, 0x2801, 0x2d15, 0x6012, 0x0024, 0x0000, + 0x0024, 0x2801, 0x2d15, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3e13, 0xb80f, + 0xf400, 0x4500, 0x0026, 0x9dcf, 0x0001, 0x20ce, 0x0000, 0xfa0d, 0x2926, + 0x8e80, 0x3e10, 0x110c, 0x36f3, 0x0024, 0x2801, 0x2d00, 0x36f3, 0x980f, + 0x001c, 0xdd00, 0x001c, 0xd901, 0x6ec2, 0x0024, 0x001c, 0xdd00, 0x2801, + 0x23d5, 0x0018, 0xdbc1, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0xc640, + 0x3e00, 0x13cc, 0x2801, 0x2ac0, 0x36f3, 0x0024, 0x6ec2, 0x0024, 0x003f, + 0xc000, 0x2801, 0x2655, 0x002a, 0x4001, 0x3413, 0x184c, 0xf400, 0x4500, + 0x2926, 0xafc0, 0x3e00, 0x13cc, 0x2801, 0x2ac0, 0x36f3, 0x0024, 0xb400, + 0x0024, 0xd100, 0x0024, 0x0000, 0x0024, 0x2801, 0x2ac5, 0x0000, 0x0024, + 0x3613, 0x0024, 0x3e11, 0x4024, 0x2926, 0x8540, 0x3e01, 0x0024, 0x4080, + 0x1b8c, 0x0000, 0x0024, 0x2801, 0x2ac5, 0x0000, 0x0024, 0x3413, 0x184c, + 0xf400, 0x4500, 0x2926, 0x8e80, 0x3e10, 0x13cc, 0x36f3, 0x0024, 0x3110, + 0x8024, 0x31f0, 0xc024, 0x0000, 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, + 0x3110, 0x8024, 0x2826, 0xa8c4, 0x31f0, 0xc024, 0x2a26, 0xad00, 0x34c3, + 0x184c, 0x3410, 0x8024, 0x3430, 0xc024, 0x0000, 0x4000, 0x0000, 0x0021, + 0x6d06, 0x0024, 0x0000, 0x0024, 0x2801, 0x3394, 0x4d06, 0x0024, 0x0000, + 0x0200, 0x2922, 0x1885, 0x0001, 0x3208, 0x0000, 0x0200, 0x3e10, 0x8024, + 0x2921, 0xca80, 0x3e00, 0xc024, 0x291a, 0x8a40, 0x0000, 0x0024, 0x2922, + 0x1880, 0x36f3, 0x0024, 0x0000, 0x004d, 0x0021, 0x0ecf, 0x2821, 0x0bc0, + 0x0001, 0x330e, 0x2801, 0x1600, 0x3c30, 0x4024, 0x0000, 0x190d, 0x0000, + 0x458e, 0x2821, 0x0f80, 0x0027, 0x9e0f, 0x0020, 0xcd4f, 0x2820, 0xc780, + 0x0001, 0x354e, 0x0006, 0xf017, 0x0000, 0x0015, 0xb070, 0xbc15, 0x0000, + 0x458e, 0x0027, 0x9e0f, 0x2820, 0xcd80, 0x0000, 0x190d, 0x3613, 0x0024, + 0x3e10, 0xb803, 0x3e14, 0x3811, 0x3e11, 0x3805, 0x3e00, 0x3801, 0x0007, + 0xc390, 0x0006, 0xa011, 0x3010, 0x0444, 0x3050, 0x4405, 0x6458, 0x0302, + 0xff94, 0x4081, 0x0003, 0xffc5, 0x48b6, 0x0024, 0xff82, 0x0024, 0x42b2, + 0x0042, 0xb458, 0x0003, 0x4cd6, 0x9801, 0xf248, 0x1bc0, 0xb58a, 0x0024, + 0x6de6, 0x1804, 0x0006, 0x0010, 0x3810, 0x9bc5, 0x3800, 0xc024, 0x36f4, + 0x1811, 0x36f0, 0x9803, 0x283e, 0x2d80, 0x0fff, 0xffc3, 0x2801, 0x4b80, + 0x0000, 0x0024, 0x3413, 0x0024, 0x2801, 0x3f85, 0xf400, 0x4517, 0x2801, + 0x4380, 0x6894, 0x13cc, 0x37b0, 0x184c, 0x6090, 0x1d51, 0x0000, 0x0910, + 0x3f00, 0x060c, 0x3100, 0x4024, 0x6016, 0xb812, 0x000c, 0x8012, 0x2801, + 0x4211, 0xb884, 0x0024, 0x6894, 0x3002, 0x0000, 0x028d, 0x003a, 0x5e0f, + 0x0001, 0x538e, 0x2939, 0xb0c0, 0x3e10, 0x93cc, 0x4084, 0x9bd2, 0x4282, + 0x0024, 0x0000, 0x0040, 0x2801, 0x4585, 0x4292, 0x130c, 0x3443, 0x0024, + 0x2801, 0x46c5, 0x000c, 0x8390, 0x2a01, 0x4a40, 0x3444, 0x0024, 0x3073, + 0x0024, 0xc090, 0x014c, 0x2801, 0x4a40, 0x3800, 0x0024, 0x000c, 0x4113, + 0xb880, 0x2380, 0x3304, 0x4024, 0x3800, 0x05cc, 0xcc92, 0x05cc, 0x3910, + 0x0024, 0x3910, 0x4024, 0x000c, 0x8110, 0x3910, 0x0024, 0x39f0, 0x4024, + 0x3810, 0x0024, 0x38d0, 0x4024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x34c3, + 0x0024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, 0x4284, 0x0024, 0x3613, + 0x0024, 0x2801, 0x4d85, 0x6898, 0xb804, 0x0000, 0x0084, 0x293b, 0x1cc0, + 0x3613, 0x0024, 0x000c, 0x8117, 0x3711, 0x0024, 0x37d1, 0x4024, 0x4e8a, + 0x0024, 0x0000, 0x0015, 0x2801, 0x5045, 0xce9a, 0x0024, 0x3f11, 0x0024, + 0x3f01, 0x4024, 0x000c, 0x8197, 0x408a, 0x9bc4, 0x3f15, 0x4024, 0x2801, + 0x5285, 0x4284, 0x3c15, 0x6590, 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, + 0x4284, 0x0024, 0x0000, 0x0024, 0x2801, 0x3e58, 0x458a, 0x0024, 0x2a39, + 0x53c0, 0x003e, 0x2d4f, 0x283a, 0x5ed5, 0x0001, 0x370e, 0x000c, 0x4653, + 0x0000, 0x0246, 0xffac, 0x0c01, 0x48be, 0x0024, 0x4162, 0x4546, 0x6642, + 0x4055, 0x3501, 0x8024, 0x0000, 0x0087, 0x667c, 0x4057, 0x000c, 0x41d5, + 0x283a, 0x62d5, 0x3501, 0x8024, 0x667c, 0x1c47, 0x3701, 0x8024, 0x283a, + 0x62d5, 0xc67c, 0x0024, 0x0000, 0x0024, 0x283a, 0x62c5, 0x0000, 0x0024, + 0x2a3a, 0x5ec0, 0x3009, 0x3851, 0x3e14, 0xf812, 0x3e12, 0xb817, 0x3e11, + 0x8024, 0x0006, 0x0293, 0x3301, 0x8024, 0x468c, 0x3804, 0x0006, 0xa057, + 0x2801, 0x5f84, 0x0006, 0x0011, 0x469c, 0x0024, 0x3be1, 0x8024, 0x2801, + 0x5f95, 0x0006, 0xc392, 0x3311, 0x0024, 0x33f1, 0x2844, 0x3009, 0x2bc4, + 0x0030, 0x04d2, 0x3311, 0x0024, 0x3a11, 0x0024, 0x3201, 0x8024, 0x003f, + 0xfc04, 0xb64c, 0x0fc4, 0xc648, 0x0024, 0x3a01, 0x0024, 0x3111, 0x1fd3, + 0x6498, 0x07c6, 0x868c, 0x2444, 0x0023, 0xffd2, 0x3901, 0x8e06, 0x0030, + 0x0551, 0x3911, 0x8e06, 0x3961, 0x9c44, 0xf400, 0x44c6, 0xd46c, 0x1bc4, + 0x36f1, 0xbc13, 0x2801, 0x6915, 0x36f2, 0x9817, 0x002b, 0xffd2, 0x3383, + 0x188c, 0x3e01, 0x8c06, 0x0006, 0xa097, 0x3009, 0x1c12, 0x3213, 0x0024, + 0x468c, 0xbc12, 0x002b, 0xffd2, 0xf400, 0x4197, 0x2801, 0x6604, 0x3713, + 0x0024, 0x2801, 0x6645, 0x37e3, 0x0024, 0x3009, 0x2c17, 0x3383, 0x0024, + 0x3009, 0x0c06, 0x468c, 0x4197, 0x0006, 0xa052, 0x2801, 0x6844, 0x3713, + 0x2813, 0x2801, 0x6885, 0x37e3, 0x0024, 0x3009, 0x2c17, 0x36f1, 0x8024, + 0x36f2, 0x9817, 0x36f4, 0xd812, 0x2100, 0x0000, 0x3904, 0x5bd1, 0x2a01, + 0x594e, 0x3e11, 0x7804, 0x0030, 0x0257, 0x3701, 0x0024, 0x0013, 0x4d05, + 0xd45b, 0xe0e1, 0x0007, 0xc795, 0x2801, 0x7095, 0x0fff, 0xff45, 0x3511, + 0x184c, 0x4488, 0xb808, 0x0006, 0x8a97, 0x2801, 0x7045, 0x3009, 0x1c40, + 0x3511, 0x1fc1, 0x0000, 0x0020, 0xac52, 0x1405, 0x6ce2, 0x0024, 0x0000, + 0x0024, 0x2801, 0x7041, 0x68c2, 0x0024, 0x291a, 0x8a40, 0x3e10, 0x0024, + 0x2921, 0xca80, 0x3e00, 0x4024, 0x36f3, 0x0024, 0x3009, 0x1bc8, 0x36f0, + 0x1801, 0x3601, 0x5804, 0x3e13, 0x780f, 0x3e13, 0xb808, 0x0008, 0x9b0f, + 0x0001, 0x734e, 0x2908, 0x9300, 0x0000, 0x004d, 0x36f3, 0x9808, 0x2000, + 0x0000, 0x36f3, 0x580f, 0x0007, 0x81d7, 0x3711, 0x8024, 0x3711, 0xc024, + 0x3700, 0x0024, 0x0000, 0x2001, 0xb012, 0x0024, 0x0034, 0x0000, 0x2801, + 0x78c5, 0x0000, 0x01c1, 0x3700, 0x0024, 0x0002, 0x0001, 0xb012, 0x0024, + 0x002e, 0xe001, 0x2801, 0x77c5, 0x6512, 0x0024, 0x0034, 0x0000, 0x2801, + 0x78d5, 0x0000, 0x01c1, 0x0030, 0x0117, 0x3f00, 0x0024, 0x0014, 0xc000, + 0x0000, 0x01c1, 0x4fce, 0x0024, 0xffea, 0x0024, 0x48b6, 0x0024, 0x4384, + 0x4097, 0xb886, 0x45c6, 0xfede, 0x0024, 0x4db6, 0x0024, 0x466c, 0x0024, + 0x0006, 0xc610, 0x8dd6, 0x8007, 0x0000, 0x00c6, 0xff6e, 0x0024, 0x48b2, + 0x0024, 0x0034, 0x2406, 0xffee, 0x0024, 0x2914, 0xaa80, 0x40b2, 0x0024, + 0xf1c6, 0x0024, 0xf1d6, 0x0024, 0x0000, 0x0201, 0x8d86, 0x0024, 0x61de, + 0x0024, 0x0006, 0xc612, 0x2801, 0x7f41, 0x0006, 0xc713, 0x4c86, 0x0024, + 0x2912, 0x1180, 0x0006, 0xc351, 0x0006, 0x0210, 0x2912, 0x0d00, 0x3810, + 0x984c, 0xf200, 0x2043, 0x2808, 0xa000, 0x3800, 0x0024, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x7802, 0x3e04, 0x3811, 0x34a3, 0x0024, 0x3470, 0x0024, + 0x2801, 0x88c0, 0x3cf0, 0x0024, 0x0000, 0xfa01, 0x3e10, 0x0024, 0x3410, + 0x0024, 0x3e10, 0x0024, 0x3410, 0x0024, 0x3e10, 0x0024, 0x3430, 0x0024, + 0x2920, 0x0600, 0x3e00, 0x0024, 0x36c3, 0x128c, 0xf400, 0x4510, 0x3420, + 0x0024, 0x6012, 0x4511, 0x3800, 0x4024, 0x0000, 0x7d01, 0x3440, 0x0024, + 0x4012, 0x0024, 0x3900, 0x4024, 0x0000, 0xfa00, 0x34a3, 0x184c, 0x3410, + 0x4024, 0x6014, 0x0024, 0x0000, 0x0024, 0x2801, 0x8451, 0x0000, 0x0024, + 0x3e10, 0x4024, 0x3410, 0x0024, 0x3e10, 0x0024, 0x3410, 0x0024, 0x3e10, + 0x0024, 0x3430, 0x0024, 0x2920, 0x0600, 0x3e00, 0x0024, 0x36c3, 0x104c, + 0x34f0, 0x1811, 0x36f4, 0x0024, 0x36f0, 0x5802, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x0000, 0x0081, 0x3e10, 0xb804, 0x3e14, 0x3811, + 0x0006, 0x9f90, 0x3e04, 0xb813, 0x3009, 0x0000, 0x6012, 0x0024, 0x0000, + 0x0000, 0x6104, 0xa001, 0x0000, 0x0940, 0x2801, 0x94c1, 0xb882, 0x0024, + 0x0001, 0x0001, 0x3009, 0x0000, 0x4012, 0x0024, 0x0000, 0x0940, 0xb882, + 0xa001, 0x0000, 0xa992, 0x0007, 0xc051, 0x2914, 0xbec0, 0x0007, 0xc010, + 0x0001, 0x8150, 0x003f, 0xffc0, 0x001f, 0xffc1, 0x3944, 0x0024, 0x0007, + 0xd010, 0x3974, 0x8024, 0x0030, 0x0252, 0x4890, 0x2780, 0x3910, 0x0024, + 0x39d0, 0x4024, 0x3910, 0x0024, 0x2902, 0x0600, 0x39f0, 0x4024, 0x3800, + 0x0024, 0x0011, 0x14c0, 0x3a00, 0x0024, 0x3000, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0024, 0x2801, 0x9d85, 0x0000, 0x0024, 0x3413, 0x184c, 0x2b50, + 0x4013, 0x3e11, 0x0c8c, 0x0007, 0xc004, 0x3e11, 0x13cc, 0x3e00, 0x0024, + 0x3302, 0x0024, 0x2000, 0x0000, 0x0001, 0x9d48, 0x36d3, 0x0024, 0x36f4, + 0x9813, 0x36f4, 0x1811, 0x36f0, 0x9804, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb813, 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, 0xf804, + 0x3e11, 0x7806, 0x3e11, 0xf80d, 0x3e13, 0xf80e, 0xf400, 0x4455, 0x6804, + 0x1444, 0xf400, 0x4417, 0x2801, 0xb458, 0x4094, 0x1453, 0x0000, 0x0051, + 0x0fff, 0xff01, 0x2401, 0xb402, 0x3700, 0x8024, 0x003f, 0xc007, 0xb274, + 0x0024, 0xc428, 0x3812, 0x0020, 0x07d2, 0x0003, 0xffc7, 0xb47c, 0x0e0c, + 0x0008, 0x0003, 0x4360, 0x0024, 0xa41c, 0x4010, 0xb67c, 0x0002, 0x4360, + 0x2e02, 0x0000, 0x0206, 0xb58a, 0x1c04, 0xae6a, 0x4010, 0xc548, 0x0002, + 0xb47c, 0x2e02, 0x4360, 0x148c, 0xa41c, 0x4010, 0xb67c, 0x0002, 0x4360, + 0x2e02, 0xf400, 0x4010, 0x3711, 0x3813, 0x0000, 0x3fc6, 0xb468, 0x0000, + 0xb78e, 0x1786, 0x0028, 0x07d2, 0x4ffe, 0x0024, 0x4ffe, 0x1490, 0xbd87, + 0xb80d, 0xfe51, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, + 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, + 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x505f, 0x380d, 0x505f, 0x380d, + 0x505f, 0x380d, 0x505f, 0x380d, 0x505f, 0x380d, 0x505f, 0x380d, 0x505f, + 0x380d, 0x505f, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, + 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, + 0x3005, 0x5056, 0x1812, 0x4db6, 0x9813, 0x0fff, 0xff40, 0xad06, 0x0024, + 0x4fde, 0x0024, 0xf1fe, 0x1c02, 0xf1fe, 0x0024, 0xf6fe, 0x3786, 0x3009, + 0x2847, 0x35f3, 0x0024, 0x3df4, 0xc024, 0x3d01, 0x1bcc, 0x36f3, 0xd80e, + 0x36f1, 0xd80d, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x2000, + 0x0000, 0x36f2, 0x9813, 0x3613, 0x0024, 0x3e12, 0xb813, 0x0000, 0x800a, + 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7806, 0x3e11, 0xf80d, 0x3e13, + 0xf80e, 0x3009, 0x3854, 0xf400, 0x4455, 0x6804, 0x1444, 0xf400, 0x4417, + 0x2801, 0xcc18, 0x4094, 0x1453, 0x0fff, 0xff01, 0x0000, 0x0051, 0x2401, + 0xcbc2, 0x3700, 0x8024, 0x0fff, 0xfe07, 0xa274, 0x3812, 0x0000, 0x3fc7, + 0xb274, 0x0024, 0x0020, 0x07d2, 0xc428, 0x0e0c, 0xa41c, 0x0024, 0x0003, + 0xffc7, 0xb67c, 0x0024, 0x0008, 0x0003, 0x4360, 0x0024, 0xf400, 0x4010, + 0xb47c, 0x0002, 0x4360, 0x2e02, 0x3701, 0x0024, 0xa41c, 0x4010, 0x3000, + 0x8024, 0xb67c, 0x2e02, 0x4360, 0x948c, 0xf400, 0x4010, 0xb47c, 0x0002, + 0x4360, 0x2e02, 0xf400, 0x4010, 0x3711, 0x3813, 0x0000, 0x0206, 0xa468, + 0x0000, 0xb78e, 0x1786, 0x0028, 0x07d2, 0x4ffe, 0x0024, 0x4ffe, 0x1490, + 0xbd87, 0xb80d, 0xfe51, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, + 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, + 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x505f, 0x380d, 0x505f, + 0x380d, 0x505f, 0x380d, 0x505f, 0x380d, 0x505f, 0x380d, 0x505f, 0x380d, + 0x505f, 0x380d, 0x505f, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, + 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, 0x5057, 0x380d, + 0x5057, 0x3005, 0x5056, 0x1812, 0x4db6, 0x9813, 0x0fff, 0xff40, 0xad06, + 0x0024, 0x4fde, 0x0024, 0xf1fe, 0x1c02, 0xf1fe, 0x0024, 0xf6fe, 0x3786, + 0x3009, 0x2847, 0x35f3, 0x0024, 0x3df4, 0xdbcc, 0x3d01, 0x1bd4, 0x36f3, + 0xd80e, 0x36f1, 0xd80d, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, + 0x2000, 0x0000, 0x36f2, 0x9813, 0x3613, 0x0024, 0x3e12, 0xb815, 0x0000, + 0x800a, 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7806, 0x3e11, 0xf813, + 0x3e13, 0xf80e, 0x3e03, 0x7814, 0xf400, 0x4497, 0x6804, 0x044c, 0x0000, + 0x0024, 0x2801, 0xdb18, 0x4094, 0x0024, 0xf224, 0x0024, 0x2401, 0xdac2, + 0x0000, 0x0055, 0x0028, 0x07d3, 0x3114, 0x8024, 0x31f5, 0x0024, 0x3283, + 0x0040, 0x3a80, 0x0040, 0x3a00, 0x0024, 0xbe8a, 0x2412, 0x0020, 0x07d3, + 0xbd87, 0x2849, 0xfe11, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x501b, 0x2849, 0x501b, 0x2849, + 0x501b, 0x2849, 0x501b, 0x2849, 0x501b, 0x2849, 0x501b, 0x2849, 0x501b, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5016, 0x0024, + 0x4db6, 0x0024, 0x0fff, 0xff40, 0xad06, 0x0024, 0x4eda, 0x0024, 0xf7ea, + 0x0024, 0x3f11, 0x4024, 0x3f18, 0x8024, 0x36f3, 0x5814, 0x36f3, 0xd80e, + 0x36f1, 0xd813, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x2000, + 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, 0x3e12, 0xb814, 0x0000, 0x800a, + 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7806, 0x3e11, 0xf813, 0x3e13, + 0xf80e, 0x3e03, 0x4024, 0x6804, 0x044c, 0x0000, 0x0024, 0x2801, 0xf758, + 0x4094, 0x4497, 0xf224, 0x0024, 0x2401, 0xf702, 0x0000, 0x0095, 0x0028, + 0x7fd3, 0xbe8a, 0x0452, 0x31f5, 0x0a0c, 0x3010, 0x0024, 0x3010, 0x4024, + 0x3a80, 0x4024, 0x3a80, 0x0024, 0x3010, 0x0024, 0x3010, 0x4024, 0x3a80, + 0x4024, 0x3a00, 0x3812, 0x0010, 0x41d3, 0xbd87, 0x2849, 0xfe11, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2041, 0x3223, + 0x104c, 0x501b, 0x2041, 0x32e3, 0x13cc, 0x3283, 0x120c, 0x501b, 0x2849, + 0x501b, 0x2849, 0x501b, 0x2849, 0x501b, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, + 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, 0x2849, 0x5017, + 0x2849, 0x5016, 0x9812, 0x4db6, 0x2452, 0x0fff, 0xff40, 0xad06, 0x07d4, + 0x4dee, 0x084c, 0x3f11, 0x8024, 0x3f31, 0xc024, 0x36f3, 0x4024, 0x36f3, + 0xd80e, 0x36f1, 0xd813, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, + 0x2000, 0x0000, 0x36f2, 0x9814, 0x3613, 0x0024, 0x3e12, 0xb815, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x780d, 0x6840, 0xb80e, + 0x0000, 0x0024, 0x2801, 0xfe18, 0x4490, 0x380f, 0xf200, 0x0024, 0x003f, + 0xc001, 0x2401, 0xfdc0, 0x0000, 0x0200, 0xb386, 0x0445, 0xb51a, 0x0442, + 0xad06, 0x0024, 0xc356, 0x0024, 0x3810, 0xc024, 0x36f3, 0xd80e, 0x36f1, + 0x580d, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x2000, 0x0000, 0x36f2, 0x9815, + 0x3613, 0x0024, 0x3e12, 0xb815, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, + 0xb805, 0x3e13, 0xf80e, 0x3e03, 0x4024, 0x6840, 0x0024, 0x0000, 0x0024, + 0x2802, 0x0498, 0x4490, 0x0024, 0x0000, 0x0201, 0xf200, 0x0024, 0x2402, + 0x0440, 0x0000, 0x3fc2, 0x3110, 0x0024, 0xa010, 0x0445, 0xb52a, 0x0024, + 0xc050, 0x0024, 0x3810, 0x0024, 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x36f0, + 0x9805, 0x36f0, 0x1801, 0x2000, 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x3e10, + 0x7810, 0x0003, 0xf410, 0xb882, 0x3811, 0x0002, 0x0611, 0x3009, 0x3812, + 0x0002, 0x0d12, 0x2914, 0xbec0, 0x0000, 0x0700, 0x0003, 0xf410, 0x0000, + 0x4140, 0x3810, 0x0024, 0x0003, 0xf400, 0x3824, 0x4024, 0x0002, 0x70d1, + 0x38f4, 0x9812, 0x3804, 0x4024, 0x36f4, 0x4024, 0x36f0, 0x5810, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0x3613, 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x3405, + 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x0000, 0x0200, + 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3655, + 0x0024, 0x0000, 0x800a, 0x3e10, 0xb804, 0x3e11, 0x7810, 0x3e14, 0x504c, + 0xb880, 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x130c, 0x3430, + 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, 0x0024, 0x2000, 0x0000, + 0x0002, 0x1408, 0x0000, 0x0201, 0x6012, 0x9b4c, 0x3413, 0x0024, 0x2802, + 0x1601, 0xf400, 0x4511, 0x34f3, 0x1bcc, 0x2802, 0x1880, 0xbc82, 0x0024, + 0x2900, 0x5b40, 0x3100, 0x93cc, 0xb182, 0x184c, 0x3113, 0x3840, 0x2900, + 0x5b40, 0x3100, 0x8024, 0x4088, 0x9bc0, 0xf400, 0x4105, 0x0000, 0x0004, + 0xcce2, 0x0024, 0x36f4, 0x4024, 0x36f1, 0x5810, 0x36f0, 0x9804, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0x0000, 0x0200, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x3655, 0x0024, 0x0000, 0x800a, 0x3e11, 0x3805, 0x3e14, 0x3811, + 0x3e10, 0x104c, 0xb880, 0x0024, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, + 0x130c, 0x3430, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, 0x0024, + 0x2000, 0x0000, 0x0002, 0x1f88, 0x0000, 0x0201, 0x6012, 0x9b0c, 0x3443, + 0x0024, 0x2802, 0x2141, 0xf400, 0x4511, 0x2802, 0x2280, 0xbc82, 0x130c, + 0x31f0, 0x130c, 0xb182, 0x0404, 0xf400, 0x4105, 0x0000, 0x0004, 0xcce2, + 0x0024, 0x36f4, 0x1811, 0x36f1, 0x1805, 0x3405, 0x9014, 0x36f3, 0x0024, + 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x0000, 0x0100, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, + 0x0000, 0x800a, 0x3e10, 0xb804, 0x3e11, 0x7810, 0x3e14, 0x504c, 0xb880, + 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x130c, 0x3430, 0x0024, + 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, 0x0024, 0x2000, 0x0000, 0x0002, + 0x2948, 0x0000, 0x0101, 0x6012, 0x9b4c, 0x3413, 0x0024, 0x2802, 0x2b41, + 0xf400, 0x4511, 0x34f3, 0x1bcc, 0x2802, 0x2dc0, 0xbc82, 0x0024, 0x2900, + 0x5b40, 0x3100, 0x93cc, 0xb182, 0x184c, 0x3113, 0x3840, 0x2900, 0x5b40, + 0x3100, 0x8024, 0x4088, 0x9bc0, 0xf400, 0x4105, 0x0000, 0x0004, 0xcce2, + 0x0024, 0x36f4, 0x4024, 0x36f1, 0x5810, 0x36f0, 0x9804, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x0000, + 0x0100, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, + 0x3635, 0x0024, 0x0000, 0x800a, 0x3e11, 0x3805, 0x3e14, 0x3811, 0x3e10, + 0x104c, 0xb880, 0x0024, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x130c, + 0x3430, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, 0x0024, 0x2000, + 0x0000, 0x0002, 0x34c8, 0x0000, 0x0101, 0x6012, 0x9b0c, 0x3423, 0x0024, + 0x2802, 0x3681, 0xf400, 0x4511, 0x2802, 0x37c0, 0xbc82, 0x138c, 0x31f0, + 0x138c, 0xb182, 0x0404, 0xf400, 0x4105, 0x0000, 0x0004, 0xcce2, 0x0024, + 0x36f4, 0x1811, 0x36f1, 0x1805, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, + 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x0000, 0x0080, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, 0x0000, + 0x800a, 0x3e14, 0x3811, 0x3e10, 0x104c, 0xb880, 0x0024, 0x3e10, 0x0024, + 0xf400, 0x4500, 0x3e10, 0x130c, 0x3430, 0x0024, 0xf400, 0x4010, 0x3e00, + 0x004c, 0x3002, 0x0024, 0x2000, 0x0000, 0x0002, 0x3e48, 0x0000, 0x0081, + 0x6012, 0x1b0c, 0x0000, 0x0024, 0x2802, 0x4001, 0xb182, 0x104c, 0x2802, + 0x4040, 0xbc82, 0x13cc, 0x34f0, 0x0024, 0x36f4, 0x1811, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, 0x3645, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb804, 0x3e11, 0x7806, 0x3e11, 0xf810, 0x3e14, + 0x780d, 0x3e03, 0xf80e, 0x0003, 0xffce, 0xb880, 0x108c, 0x3c10, 0x0024, + 0x3ce0, 0x0024, 0x2402, 0x6e0e, 0x3cf0, 0x0024, 0x0006, 0x18d0, 0xbe8a, + 0x104c, 0x6892, 0x13c0, 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, 0x0024, + 0x2802, 0x4885, 0xfe02, 0x0024, 0x2802, 0x48c0, 0x4eba, 0x0024, 0x6eba, + 0x0024, 0x0000, 0x0081, 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, + 0x0000, 0x0024, 0x2802, 0x4b45, 0x4192, 0x0000, 0xfe02, 0x0024, 0x2802, + 0x4bc0, 0x4eba, 0x0024, 0xfe02, 0x0024, 0x6eba, 0x0024, 0x0000, 0x0101, + 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, + 0x0024, 0x2802, 0x4e45, 0xfe02, 0x0024, 0x2802, 0x4e80, 0x4eba, 0x0024, + 0x6eba, 0x0024, 0x0000, 0x0201, 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0041, 0x3000, 0x0024, 0x2802, 0x5105, 0xfe02, 0x0024, + 0x2802, 0x5140, 0x4eba, 0x0024, 0x6eba, 0x0024, 0x0000, 0x0401, 0x3413, + 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, 0x0024, + 0x2802, 0x53c5, 0xfe02, 0x0024, 0x2802, 0x5400, 0x4eba, 0x0024, 0x6eba, + 0x0024, 0x0000, 0x0801, 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, + 0x0000, 0x0041, 0x3000, 0x0024, 0x2802, 0x5685, 0xfe02, 0x0024, 0x2802, + 0x56c0, 0x4eba, 0x0024, 0x6eba, 0x0024, 0x0000, 0x1001, 0x3413, 0x004c, + 0x34f0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, 0x0024, 0x2802, + 0x5945, 0xfe02, 0x0024, 0x2802, 0x5980, 0x4eba, 0x0024, 0x6eba, 0x0024, + 0x0000, 0x2001, 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, 0x0000, + 0x0041, 0x3000, 0x0024, 0x2802, 0x5c05, 0xfe02, 0x0024, 0x2802, 0x5c40, + 0x4eba, 0x0024, 0x6eba, 0x0024, 0x0000, 0x4001, 0x3413, 0x004c, 0x34f0, + 0x0024, 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, 0x0024, 0x2802, 0x5ec5, + 0xfe02, 0x0024, 0x2802, 0x5f00, 0x4eba, 0x0024, 0x6eba, 0x0024, 0x0000, + 0x8001, 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0041, + 0x3000, 0x0024, 0x2802, 0x6185, 0xfe02, 0x0024, 0x2802, 0x61c0, 0x4eba, + 0x0024, 0x6eba, 0x0024, 0x0001, 0x0001, 0x3413, 0x004c, 0x34f0, 0x0024, + 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, 0x0024, 0x2802, 0x6445, 0xfe02, + 0x0024, 0x2802, 0x6480, 0x4eba, 0x0024, 0x6eba, 0x0024, 0x0002, 0x0001, + 0x3413, 0x004c, 0x34f0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0041, 0x3000, + 0x0024, 0x2802, 0x6705, 0xfe02, 0x0024, 0x2802, 0x6740, 0x4eba, 0x0024, + 0x6eba, 0x0024, 0xf1ea, 0x104c, 0x4e82, 0x1042, 0x0008, 0x0001, 0x4122, + 0x0024, 0xf400, 0x4055, 0x0000, 0x0041, 0x3d00, 0x0024, 0x3410, 0x0024, + 0xfe02, 0x0024, 0x48b2, 0x0024, 0x6cee, 0x1380, 0x0000, 0x0041, 0x2802, + 0x6bc9, 0xfe02, 0x4511, 0x3413, 0x0024, 0x3c11, 0x0024, 0x34e0, 0x0024, + 0xfe02, 0x4511, 0x48b2, 0x0024, 0x6cee, 0x1080, 0x0000, 0x0024, 0x2802, + 0x6dd8, 0x0000, 0x0024, 0x3ce1, 0x0024, 0xf400, 0x4511, 0x3420, 0x0024, + 0x6090, 0x934c, 0x3900, 0x0024, 0x36f3, 0xd80e, 0x36f4, 0x580d, 0x36f1, + 0xd810, 0x36f1, 0x5806, 0x36f0, 0x9804, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x0000, 0x0657, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3685, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7806, 0x3e11, + 0xf810, 0x3e14, 0x7812, 0x3e04, 0xd34c, 0x2902, 0x41c0, 0x6898, 0x10d2, + 0xf400, 0x4490, 0x34c3, 0x010c, 0x34f0, 0x184c, 0x3800, 0x0024, 0x3460, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0100, 0x2802, 0x7805, 0x0000, 0x0024, + 0x0006, 0x0580, 0x3009, 0x128c, 0x3464, 0x4024, 0x3900, 0x0024, 0x0000, + 0x0100, 0xb880, 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x12cc, + 0x3440, 0x0024, 0xf400, 0x4011, 0x3e00, 0x044c, 0x3102, 0x0024, 0x2000, + 0x0000, 0x0002, 0x7a88, 0x0000, 0x0101, 0x6012, 0x9b0c, 0x0012, 0x5101, + 0x2802, 0x7c41, 0x3413, 0x0024, 0x2803, 0xd9c0, 0x4480, 0x13cc, 0xf400, + 0x4510, 0x34f0, 0x004c, 0x6012, 0x0000, 0x003f, 0xc001, 0x2802, 0x9515, + 0xb010, 0x0024, 0x000c, 0xc001, 0x6012, 0x0024, 0x0000, 0x0024, 0x2802, + 0x9515, 0x0000, 0x0024, 0xb880, 0x110c, 0x3cd0, 0x184c, 0x0000, 0x0080, + 0xb880, 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x12cc, 0x3440, + 0x0024, 0x3e00, 0x0024, 0x3102, 0x0024, 0x2000, 0x0000, 0x0002, 0x8208, + 0x0000, 0x0100, 0x36d3, 0x104c, 0xb880, 0x3840, 0x3e10, 0x0024, 0xf400, + 0x4500, 0x3e10, 0x12cc, 0x3440, 0x0024, 0x3e00, 0x0024, 0x3102, 0x0024, + 0x2000, 0x0000, 0x0002, 0x84c8, 0x001f, 0xc001, 0x0000, 0x1fc2, 0x3123, + 0x108c, 0xf400, 0x4510, 0x34e0, 0x1b0c, 0xb010, 0x0081, 0xf200, 0x0024, + 0xb122, 0x0024, 0x4010, 0x0024, 0x3800, 0x0024, 0x31f0, 0x0024, 0x4080, + 0x0024, 0x3100, 0x0024, 0x2802, 0x8c85, 0x4080, 0x0024, 0x0000, 0x0043, + 0x34c3, 0x184c, 0x6890, 0x844c, 0x3e10, 0x0024, 0x3000, 0x8024, 0xfe26, + 0x0024, 0x48b6, 0x0024, 0x3e10, 0x8024, 0x3e10, 0xc024, 0x3440, 0x0024, + 0x3e00, 0x0024, 0x3102, 0x0024, 0x2000, 0x0000, 0x0002, 0x8c08, 0x2802, + 0x9040, 0x36c3, 0x0024, 0x0000, 0x0024, 0x2802, 0x9045, 0x0000, 0x0024, + 0x0000, 0x0041, 0x3000, 0x184c, 0xfe02, 0x930c, 0x48b2, 0x0024, 0x3e10, + 0x0024, 0x3e10, 0x4024, 0x3440, 0xc024, 0x3e00, 0xc024, 0x3102, 0x0024, + 0x2000, 0x0000, 0x0002, 0x9008, 0x36d3, 0x0024, 0x0000, 0x0100, 0x3613, + 0x104c, 0xb880, 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x12cc, + 0x3440, 0x0024, 0xf400, 0x4011, 0x3e00, 0x044c, 0x3102, 0x0024, 0x2000, + 0x0000, 0x0002, 0x9348, 0x0000, 0x0101, 0x6012, 0x1b0c, 0x0000, 0x0024, + 0x2802, 0x9501, 0x0000, 0x0024, 0x2803, 0xd9c0, 0x4480, 0x0024, 0x0011, + 0x9481, 0x3413, 0x0024, 0xf400, 0x4510, 0x34f0, 0x004c, 0x6012, 0x0000, + 0x0013, 0x4e01, 0x2803, 0x1fd5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2803, + 0x1fd5, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3470, 0x8024, 0x2902, 0x1a80, + 0x3e00, 0x8024, 0x3c10, 0x0024, 0x0000, 0x0100, 0x3cd0, 0x4024, 0xb880, + 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x13cc, 0x3e00, 0x8024, + 0x3102, 0x0024, 0x2000, 0x0000, 0x0002, 0x9b88, 0x0000, 0x0101, 0x6012, + 0x9b0c, 0x0011, 0x14c1, 0x2802, 0x9d41, 0x3413, 0x0024, 0x2803, 0xd9c0, + 0x4480, 0x13cc, 0xf400, 0x4510, 0x34f0, 0x004c, 0x6012, 0x0000, 0x0011, + 0x0801, 0x2803, 0x1fd5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2803, 0x1fd5, + 0x0000, 0x0024, 0xb880, 0x11cc, 0xb882, 0x3040, 0x002b, 0x1100, 0xb888, + 0x3040, 0x3c90, 0x4024, 0x3493, 0x0024, 0x3450, 0x0024, 0x4080, 0x0024, + 0x0006, 0x0a40, 0x2803, 0x1b45, 0x0000, 0x0024, 0x34b3, 0x0024, 0x3454, + 0x0024, 0x2803, 0x1b40, 0x3800, 0x0024, 0xb880, 0x3840, 0x3e10, 0x0024, + 0xf400, 0x4500, 0x3e10, 0x12cc, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, + 0x004c, 0x3002, 0x0024, 0x2000, 0x0000, 0x0002, 0xa5c8, 0x0000, 0x0101, + 0x6012, 0x130c, 0x3440, 0x9b4c, 0x2802, 0xa781, 0xf400, 0x4100, 0x2803, + 0xd9c0, 0x3009, 0x1bcc, 0x2902, 0x1a80, 0x3e00, 0x8024, 0x36f3, 0x114c, + 0x3c10, 0x0024, 0x3cb0, 0x4024, 0xf400, 0x4511, 0x0014, 0x1481, 0x34f0, + 0x0024, 0x6012, 0x0024, 0x0013, 0xd401, 0x2803, 0x1715, 0x0000, 0x0024, + 0x3113, 0x0024, 0x3100, 0x0024, 0x6012, 0x0024, 0x0000, 0x0024, 0x2803, + 0x1715, 0x0000, 0x0024, 0x3613, 0x0024, 0x2902, 0x2440, 0x3e00, 0x8024, + 0x36f3, 0x11cc, 0x3433, 0x0024, 0x3c10, 0x0024, 0x3c90, 0x4024, 0x2803, + 0x1000, 0x34c3, 0x0024, 0xb880, 0x3840, 0x3e10, 0x0024, 0xf400, 0x4500, + 0x3e10, 0x12cc, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, + 0x0024, 0x2000, 0x0000, 0x0002, 0xb0c8, 0x0000, 0x0101, 0x6012, 0x130c, + 0x3440, 0x9b4c, 0x2802, 0xb281, 0xf400, 0x4100, 0x2803, 0xd9c0, 0x3009, + 0x1bcc, 0x2902, 0x1a80, 0x3e00, 0x8024, 0x36f3, 0x11cc, 0x3453, 0x0024, + 0x3c10, 0x0024, 0x0000, 0x0300, 0xb882, 0x33c1, 0x3411, 0x8024, 0x3491, + 0xc024, 0x6cf2, 0x13cc, 0xf400, 0x4511, 0x3110, 0x92cc, 0x31f0, 0xc024, + 0x6dc2, 0x0024, 0x3910, 0x0024, 0x39b0, 0x4024, 0x0011, 0x94c1, 0x3110, + 0x0024, 0x6012, 0x0400, 0x0008, 0x0801, 0x2802, 0xbd95, 0x6012, 0x0024, + 0x0000, 0x0024, 0x2802, 0xbd95, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3440, + 0x8024, 0x2902, 0x2fc0, 0x3e00, 0x8024, 0x0000, 0x0102, 0x36f3, 0x11cc, + 0xb886, 0x104c, 0x3c10, 0x0024, 0x3c90, 0x4024, 0x34e3, 0x0024, 0xf400, + 0x4511, 0x3173, 0x0024, 0x3153, 0x0024, 0x3110, 0x0024, 0x31f0, 0x4024, + 0x6cd6, 0x0024, 0x3910, 0x8024, 0x2803, 0x0b80, 0x39f0, 0xc024, 0x0010, + 0xd201, 0x3413, 0x0024, 0xf400, 0x4511, 0x34f0, 0x044c, 0x6012, 0x0400, + 0x0013, 0x9301, 0x2802, 0xc455, 0x6012, 0x0024, 0x0000, 0x0024, 0x2802, + 0xc455, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3440, 0x8024, 0x2902, 0x3980, + 0x3e00, 0x8024, 0x36f3, 0x11cc, 0xb882, 0x3240, 0xf400, 0x4511, 0x0000, + 0x0080, 0x3173, 0x0024, 0x3153, 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, + 0x6dc2, 0x0024, 0x3910, 0x0024, 0x2803, 0x0b80, 0x39f0, 0x4024, 0x0011, + 0x14c1, 0x3413, 0x0024, 0xf400, 0x4511, 0x34f0, 0x0024, 0x6012, 0x0024, + 0x0011, 0x0801, 0x2803, 0x0b95, 0x0000, 0x0024, 0x3113, 0x0024, 0x3100, + 0x0024, 0x6012, 0x0024, 0x0000, 0x0024, 0x2803, 0x0b95, 0x0000, 0x0024, + 0x003f, 0xfe82, 0x0000, 0x04d1, 0x3473, 0x020c, 0x3413, 0x04cc, 0x3410, + 0x0024, 0x34e0, 0x4024, 0xac22, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, + 0x0000, 0x0081, 0x3490, 0x0024, 0x34c3, 0x0024, 0x3474, 0x0024, 0x3083, + 0x110c, 0x3800, 0x0024, 0x3490, 0x0024, 0x6012, 0x130c, 0x3444, 0x0024, + 0x2802, 0xcf85, 0x3043, 0x0024, 0x34b3, 0x0024, 0x3450, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0184, 0x2802, 0xcf05, 0x0006, 0x0b00, 0x34b3, 0x0024, + 0x3454, 0x0024, 0x3800, 0x0024, 0x2803, 0xd9c0, 0x4480, 0x0024, 0x30f0, + 0x0024, 0x4080, 0x0024, 0x3000, 0x0024, 0x2803, 0x01c5, 0x4080, 0x0024, + 0x0000, 0x0024, 0x2803, 0x01c5, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3440, + 0x8024, 0xf400, 0x4090, 0x3e00, 0x810c, 0x3002, 0x0024, 0x2000, 0x0000, + 0x0002, 0xd348, 0xf400, 0x4491, 0x0000, 0x0610, 0x3473, 0x060c, 0x3910, + 0x114c, 0x3910, 0x5bcc, 0x3410, 0x0024, 0x3490, 0x4024, 0x3910, 0x128c, + 0x2803, 0x01c0, 0x39f0, 0x4024, 0x3053, 0x0024, 0x3090, 0x0024, 0x6012, + 0x038c, 0x3000, 0x0024, 0x2802, 0xecc5, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2802, 0xecc5, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3444, 0x0024, 0x3073, + 0x0024, 0x3053, 0x0024, 0x3070, 0x0024, 0x4080, 0x00cc, 0x0000, 0x0024, + 0x2802, 0xe095, 0x0000, 0x0024, 0x0000, 0x0610, 0xb880, 0x4491, 0x3e10, + 0x060c, 0x3110, 0x930c, 0x31f0, 0xc024, 0x3e10, 0x8024, 0x3e10, 0xc024, + 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x00cc, 0x3002, 0x0024, 0x2000, + 0x0000, 0x0002, 0xdd88, 0x3473, 0x048c, 0x3110, 0x114c, 0x31f0, 0x41cc, + 0x0000, 0x0411, 0x3c10, 0x010c, 0x3c90, 0x5b0c, 0xbc82, 0x124c, 0x3810, + 0x134c, 0x38f0, 0x4024, 0x3444, 0x0024, 0x2802, 0xeb00, 0x3083, 0x0024, + 0xb78e, 0x4511, 0x3090, 0x3804, 0x30d3, 0x130c, 0x3021, 0x8024, 0x3010, + 0x8024, 0x3050, 0xc024, 0x6fde, 0x0042, 0xfeae, 0x03c3, 0x0000, 0x03d0, + 0x3e00, 0xc60c, 0x48ba, 0x0024, 0xffe6, 0x0024, 0x5daa, 0x0024, 0x0000, + 0x00c2, 0x44be, 0x9804, 0xaf2e, 0x0024, 0xfff0, 0x4007, 0x48b2, 0x0024, + 0xffee, 0x0024, 0x40b2, 0x0024, 0x6890, 0x2440, 0x39f0, 0x4024, 0x3e10, + 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, 0x3e10, 0x8024, 0x3e10, 0xc024, + 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x00cc, 0x3002, 0x0024, 0x2000, + 0x0000, 0x0002, 0xe8c8, 0xf400, 0x4513, 0x3073, 0x0dcc, 0x3353, 0x008c, + 0x3310, 0x1b0c, 0x33f0, 0x4024, 0x6cd6, 0x0024, 0xb182, 0x2c42, 0x3bf0, + 0xc024, 0x3020, 0x0024, 0x3810, 0x130c, 0x003f, 0xffc0, 0x38f0, 0x4024, + 0x3444, 0x0024, 0x3073, 0x0024, 0x3053, 0x0024, 0x3800, 0x0024, 0x0004, + 0x0000, 0x3613, 0x130c, 0xb880, 0x3840, 0x3e10, 0x0024, 0x000d, 0x0000, + 0x3e10, 0x0024, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, + 0x0024, 0x2000, 0x0000, 0x0002, 0xefc8, 0x0004, 0x0001, 0x6012, 0x1b0c, + 0x0004, 0x0000, 0x2803, 0x0b91, 0x0004, 0x0010, 0xb882, 0x4511, 0x3173, + 0x184c, 0x3153, 0x3804, 0x3110, 0x8024, 0x31f0, 0xc024, 0x6dc2, 0x0024, + 0x3910, 0x0024, 0x39f0, 0x4024, 0x000d, 0x0011, 0x2901, 0xf940, 0x0002, + 0x0004, 0x0005, 0x0010, 0x000d, 0x0011, 0x0000, 0x4001, 0x2901, 0xff80, + 0x0002, 0x0004, 0x0004, 0x0010, 0x0001, 0x0000, 0x0006, 0x8091, 0x3009, + 0x1804, 0x3009, 0x3812, 0x2901, 0xb6c0, 0x0008, 0x0012, 0x0001, 0x0000, + 0x0006, 0x8311, 0x0008, 0x0010, 0x2901, 0xce80, 0x000d, 0x0012, 0x0000, + 0x8000, 0x000d, 0x0010, 0x0006, 0x8591, 0x2901, 0xdd00, 0x0002, 0x0012, + 0x0005, 0x0010, 0x0001, 0x0000, 0x0006, 0x81d1, 0x2901, 0xb6c0, 0x0008, + 0x0012, 0x0001, 0x0000, 0x0006, 0x8451, 0x0008, 0x0010, 0x2901, 0xce80, + 0x000d, 0x0012, 0x0000, 0x8000, 0x000d, 0x0010, 0x0006, 0x86d1, 0x2901, + 0xdd00, 0x0002, 0x0092, 0x0006, 0x8010, 0x3000, 0x9812, 0x6122, 0x930c, + 0x6810, 0x0024, 0x3e10, 0x0024, 0x0002, 0x0000, 0x4020, 0x0024, 0x4020, + 0x0024, 0x4020, 0x0024, 0x4020, 0x0024, 0x3e10, 0x0024, 0x3440, 0x0024, + 0xf400, 0x4011, 0x3e00, 0x054c, 0x3102, 0x0024, 0x2000, 0x0000, 0x0003, + 0x0148, 0xb880, 0x9b4c, 0x3800, 0x0024, 0x0004, 0x0000, 0xb882, 0x11cc, + 0x3453, 0x0024, 0x3410, 0x8024, 0x3490, 0xc024, 0x6dc2, 0x128c, 0x0000, + 0x0024, 0x2803, 0x0b88, 0x0000, 0x0024, 0x34c3, 0x0024, 0x3404, 0x0024, + 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, 0x0024, 0x4080, 0x1110, 0x003f, + 0xffc1, 0x2802, 0xd5c5, 0x3073, 0x0024, 0x2803, 0x0b80, 0x0000, 0x0024, + 0x3e10, 0x104c, 0xb880, 0x0024, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, + 0x12cc, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, 0x0024, + 0x2000, 0x0000, 0x0003, 0x0988, 0xf400, 0x4511, 0x36c3, 0x05cc, 0x3153, + 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, 0x4d96, 0x0024, 0x3910, 0x8024, + 0x39f0, 0xc024, 0x3473, 0x0024, 0x3453, 0x0024, 0x3410, 0x0024, 0x3490, + 0x4024, 0x4c82, 0x128c, 0x0000, 0x0024, 0x2803, 0x1009, 0x0000, 0x0024, + 0x34c3, 0x184c, 0x3444, 0x0024, 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0040, 0x2803, 0x06c5, 0x0000, 0x0024, + 0x36f3, 0x0024, 0x0000, 0x0300, 0xb882, 0x114c, 0x3410, 0x984c, 0x34b0, + 0xc024, 0x6dc2, 0x0024, 0x0000, 0x0100, 0x2802, 0xae58, 0x0000, 0x0024, + 0x2803, 0x1700, 0x36f3, 0x13cc, 0x3e10, 0x104c, 0xb880, 0x0024, 0x3e10, + 0x0024, 0xf400, 0x4500, 0x3e10, 0x12cc, 0x3440, 0x0024, 0xf400, 0x4010, + 0x3e00, 0x004c, 0x3002, 0x0024, 0x2000, 0x0000, 0x0003, 0x1548, 0x36c3, + 0x114c, 0xf400, 0x4511, 0x3110, 0x92cc, 0x31f0, 0xc024, 0x4d96, 0x0024, + 0x3910, 0x8024, 0x39f0, 0xc024, 0x3453, 0x0024, 0x3410, 0x0024, 0x34a0, + 0x4024, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2803, 0x1b45, 0x0000, 0x0024, + 0x34c3, 0x184c, 0x3444, 0x0024, 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0040, 0x2803, 0x1285, 0x0000, 0x0024, + 0x36f3, 0x0024, 0x3433, 0x0024, 0x3410, 0x8024, 0x3490, 0xc024, 0x4d86, + 0x13cc, 0x0000, 0x0024, 0x2803, 0x1f45, 0x0000, 0x0024, 0x3454, 0x184c, + 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, 0x0024, 0x4080, 0x0024, 0x0000, + 0x0100, 0x2802, 0xa345, 0x0000, 0x0024, 0x36f3, 0x12cc, 0x2803, 0xd9c0, + 0x4480, 0x110c, 0x0011, 0x14c1, 0x3413, 0x0024, 0xf400, 0x4510, 0x34f0, + 0x004c, 0x6012, 0x0000, 0x0011, 0x0801, 0x2803, 0xd3d5, 0x6012, 0x0024, + 0x0000, 0x0024, 0x2803, 0xd3d5, 0x0000, 0x0024, 0xb888, 0x12cc, 0x3410, + 0x184c, 0x4080, 0x13c2, 0x0006, 0x0a40, 0x2803, 0x2485, 0x3414, 0x0024, + 0x3800, 0x0024, 0x3400, 0x8024, 0x2902, 0x0f00, 0x3e00, 0x91cc, 0x3c10, + 0x0024, 0x3cc0, 0x4024, 0x2902, 0x0f00, 0x3e00, 0x8024, 0x2902, 0x0f00, + 0x3e00, 0x8024, 0x0000, 0x0702, 0x36f3, 0x10cc, 0xb886, 0x4510, 0x3010, + 0x134c, 0x30f0, 0x494c, 0x6cd6, 0x0024, 0x3810, 0x8024, 0x38f0, 0xc024, + 0x0019, 0x9b41, 0x32b3, 0x104c, 0xf400, 0x4510, 0x34f0, 0x004c, 0x6012, + 0x0000, 0x001d, 0x0801, 0x2803, 0x42d5, 0x6012, 0x0024, 0x0000, 0x0024, + 0x2803, 0x42d5, 0x0000, 0x0024, 0x0000, 0x0511, 0x34c3, 0x184c, 0x3470, + 0x8024, 0x2902, 0x0f00, 0x3e00, 0x8024, 0x3c10, 0x0024, 0x3cc0, 0x4024, + 0x2902, 0x2440, 0x3e00, 0x8024, 0x2902, 0x2440, 0x3e00, 0x91cc, 0x3c10, + 0x0024, 0x3c10, 0x4024, 0x2902, 0x2440, 0x3e00, 0x8024, 0x3c10, 0x0024, + 0x3c10, 0x4024, 0x2902, 0x2440, 0x3e00, 0x8024, 0x3c10, 0x0024, 0x3c90, + 0x4024, 0x2902, 0x2440, 0x3e00, 0x92cc, 0x003f, 0xfe82, 0x3009, 0x11cc, + 0x3463, 0x0024, 0x3c10, 0x0024, 0x3cf0, 0x4024, 0x3410, 0x0024, 0x3490, + 0x4024, 0x3493, 0x0024, 0xac22, 0x130c, 0x3474, 0x0024, 0x3083, 0x11cc, + 0x3810, 0x104c, 0x38f0, 0x448c, 0x3490, 0x0024, 0x3493, 0x0024, 0x34f3, + 0x0024, 0x3404, 0x0024, 0x3083, 0x0024, 0x3800, 0x0024, 0x3440, 0x8024, + 0x2902, 0x2440, 0x3e00, 0x8024, 0xf400, 0x4510, 0x0000, 0x03d1, 0x3009, + 0x020c, 0x3810, 0x0024, 0x3830, 0x4024, 0x2902, 0x0f00, 0x3e00, 0x8024, + 0x3810, 0x0024, 0x38f0, 0x4024, 0x2902, 0x2440, 0x3e00, 0x8024, 0x36f3, + 0x038c, 0x3810, 0x0024, 0x38d0, 0x4024, 0x3010, 0x0024, 0x30b0, 0x4024, + 0x4c92, 0x0024, 0x0000, 0x0080, 0x2803, 0x3c85, 0xb882, 0x0024, 0x6890, + 0x4491, 0xb882, 0x054c, 0x3900, 0x0024, 0x0000, 0x0080, 0x3010, 0x90cc, + 0x30f0, 0xc024, 0x6dc2, 0x0024, 0x0000, 0x0c00, 0x2803, 0x4105, 0xb882, + 0x0024, 0x3493, 0x0024, 0x34f3, 0x0024, 0x3450, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0184, 0x2803, 0x4085, 0x0006, 0x0b00, 0x34b3, 0x0024, 0x3454, + 0x4024, 0x3900, 0x0024, 0x2803, 0xd9c0, 0x4480, 0x0024, 0xf400, 0x4511, + 0x3110, 0x934c, 0x31f0, 0xc024, 0x6dc2, 0x0024, 0x3910, 0x0024, 0x2803, + 0xc740, 0x39f0, 0x4024, 0x0019, 0x1841, 0x3413, 0x0024, 0xf400, 0x4510, + 0x34f0, 0x004c, 0x6012, 0x0000, 0x001d, 0x1841, 0x2803, 0xc755, 0x6012, + 0x0024, 0x0000, 0x0024, 0x2803, 0xc755, 0x0000, 0x0024, 0x34c3, 0x184c, + 0x3440, 0x8024, 0x2902, 0x0f00, 0x3e00, 0x8024, 0x0000, 0x0302, 0x36f3, + 0x10cc, 0xb886, 0x3040, 0x3cf0, 0x4024, 0xf400, 0x4510, 0x3010, 0x134c, + 0x30f0, 0x4024, 0x6cd6, 0x0024, 0x3810, 0x8024, 0x3890, 0xc024, 0x30f3, + 0x0024, 0x3004, 0x4024, 0x3143, 0x0024, 0x3100, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0024, 0x2803, 0xbbc5, 0x0000, 0x0024, 0x31f3, 0x0024, 0x3100, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, 0xbbc5, 0x0000, 0x0024, + 0x3000, 0x984c, 0xf400, 0x4091, 0x3e00, 0x850c, 0x3102, 0x0024, 0x2000, + 0x0000, 0x0003, 0x4e08, 0xf400, 0x4493, 0x3073, 0x3812, 0x0000, 0x0612, + 0x3383, 0x1bd2, 0x3b10, 0x0024, 0x3b10, 0x4024, 0x3010, 0x0024, 0x30f0, + 0x4024, 0x3b10, 0x0024, 0x2803, 0xbbc0, 0x3bf0, 0x4024, 0x3483, 0x0024, + 0x1fff, 0xfb95, 0x3410, 0x0024, 0x3480, 0x4024, 0xf1c2, 0x4510, 0x003f, + 0xffc1, 0x3083, 0x130c, 0x3800, 0x0024, 0x3444, 0x4024, 0x3173, 0x0024, + 0x3153, 0x0024, 0x3190, 0x0024, 0x6012, 0x078c, 0x3100, 0x0024, 0x2803, + 0x8d05, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, 0x8d05, 0x0000, 0x0024, + 0x34c3, 0x0024, 0x3444, 0x4024, 0x3173, 0x0024, 0x3153, 0x0024, 0x3100, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, 0x6095, 0x0000, 0x0024, + 0xb880, 0x4493, 0x3613, 0x130c, 0x3e20, 0x0024, 0x3009, 0x3812, 0x0000, + 0x0612, 0x3383, 0x1bd2, 0x3310, 0x8024, 0x33f0, 0xc024, 0x3e10, 0x8024, + 0x3e10, 0xc024, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x00cc, 0x3002, + 0x0024, 0x2000, 0x0000, 0x0003, 0x5bc8, 0xf400, 0x4490, 0x0000, 0x0691, + 0x3433, 0x020c, 0x3010, 0x1b0c, 0x30f0, 0x4024, 0x0000, 0x0410, 0x3c10, + 0x0024, 0xbc82, 0x3241, 0x34f3, 0x0024, 0x3404, 0x4024, 0x3183, 0x0024, + 0x3910, 0x0024, 0x39f0, 0x4024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3073, + 0x0024, 0x3810, 0x0024, 0x2803, 0x8b80, 0x38f0, 0x4024, 0xb182, 0x048c, + 0x3111, 0x804c, 0x3151, 0xd84c, 0x6cf2, 0x0442, 0x3110, 0xd30c, 0xfea2, + 0x0024, 0x48be, 0x0024, 0xff86, 0x0024, 0x51ae, 0x0024, 0x003f, 0xfdc2, + 0x46b2, 0x0024, 0x0000, 0x0020, 0xac22, 0x0024, 0x0000, 0x0302, 0xac22, + 0x0024, 0x6890, 0x2040, 0x38f0, 0x4024, 0x3e10, 0x0024, 0x3100, 0x8024, + 0x3011, 0x8024, 0x30f1, 0xc024, 0xff74, 0x4087, 0x48b6, 0x0024, 0xffee, + 0x0024, 0x42b6, 0x0024, 0x3e10, 0x8024, 0x3e10, 0xc024, 0x3440, 0x0024, + 0xf400, 0x4013, 0x3e00, 0x0ccc, 0x3302, 0x0024, 0x2000, 0x0000, 0x0003, + 0x68c8, 0x0000, 0x05d5, 0x3100, 0x10cc, 0x0000, 0x05d1, 0x3011, 0x9b0c, + 0x30f1, 0xc024, 0xff70, 0x4007, 0x48b2, 0x4510, 0xffee, 0x934c, 0x40b2, + 0x0042, 0x30f0, 0xd20c, 0x1fff, 0xfa15, 0x4dc2, 0x0024, 0x003f, 0xff42, + 0x3810, 0x0024, 0x38f0, 0x4024, 0x3410, 0x0024, 0x3480, 0x4024, 0xac22, + 0x4510, 0x3083, 0x130c, 0x3810, 0x0024, 0x4c82, 0x23c1, 0x0000, 0x0510, + 0x2803, 0x7658, 0x4c86, 0x1111, 0x68c6, 0x060c, 0x3110, 0x0024, 0x2914, + 0xa580, 0x31f0, 0x4024, 0x0000, 0x0411, 0x0000, 0x05d5, 0x4d82, 0x130c, + 0x3444, 0x0024, 0x3083, 0x120c, 0x1fff, 0xfa15, 0x3010, 0x850c, 0x30f0, + 0xc024, 0x6dc2, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x3411, 0x8024, + 0x3481, 0xc024, 0x68f6, 0x130c, 0x3404, 0x0024, 0x3083, 0x0024, 0x3010, + 0x0024, 0x2914, 0xa580, 0x30f0, 0x4024, 0x3444, 0x0024, 0x3073, 0x0024, + 0x3073, 0x0024, 0x3010, 0x8024, 0x30f0, 0xc024, 0x2803, 0x7d80, 0x6dc2, + 0x0024, 0x3183, 0x0024, 0x3110, 0x0024, 0x2914, 0xa580, 0x31f0, 0x4024, + 0x0000, 0x0411, 0x0000, 0x05d5, 0x4d82, 0x130c, 0x3444, 0x0024, 0x3083, + 0x120c, 0x1fff, 0xfa15, 0x3010, 0x850c, 0x30f0, 0xc024, 0x4dc2, 0x0024, + 0x3810, 0x0024, 0x38f0, 0x4024, 0x3410, 0x8024, 0x3480, 0xc024, 0x34c3, + 0x0024, 0x3404, 0x0024, 0x3083, 0x0024, 0x3010, 0x0024, 0x2914, 0xa580, + 0x30f0, 0x4024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3073, 0x0024, 0x3010, + 0x8024, 0x30f0, 0xc024, 0x4dc2, 0x0024, 0x0000, 0x0411, 0x3810, 0x130c, + 0x38f0, 0x4024, 0x3404, 0x0024, 0x3083, 0x0024, 0x3010, 0x0024, 0x30f0, + 0x4024, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2803, 0x8518, 0x0000, 0x0024, + 0x3404, 0x410c, 0x3010, 0x0024, 0x30f0, 0x4024, 0x0000, 0x0410, 0x3183, + 0x0024, 0x3111, 0x8024, 0x31f1, 0xc024, 0x4fc2, 0x0024, 0x3910, 0x0024, + 0x39f0, 0x4024, 0x0000, 0x0411, 0x3404, 0x0024, 0x3073, 0x0024, 0x3073, + 0x0024, 0x3010, 0x8024, 0x30f0, 0xc024, 0x4d96, 0x0024, 0x3810, 0x8024, + 0x38f0, 0xc024, 0x3444, 0x0024, 0x3083, 0x0024, 0x3010, 0x0024, 0x3030, + 0x4024, 0x3010, 0x8024, 0x30f0, 0xc024, 0x6cde, 0x0024, 0x0000, 0x0410, + 0x2803, 0x8b91, 0x0000, 0x0024, 0x34c3, 0x0024, 0x3404, 0x4024, 0x3183, + 0x0024, 0x3111, 0x8024, 0x31f1, 0xc024, 0x6fd6, 0x0024, 0x3910, 0x8024, + 0x39f0, 0xc024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3073, 0x0024, 0x3010, + 0x0024, 0x30f0, 0x4024, 0x6c92, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, + 0x003f, 0xffc0, 0x34c3, 0x0024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3053, + 0x0024, 0x3800, 0x0024, 0x0000, 0x0551, 0xb880, 0x4510, 0x2803, 0xb040, + 0x3083, 0x0024, 0x0000, 0x0455, 0x3483, 0x184c, 0x1fff, 0xfb95, 0xb880, + 0x1046, 0x3481, 0xc024, 0x3e11, 0x930c, 0x3e10, 0x0024, 0x0004, 0x0000, + 0x3e10, 0x0024, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, + 0x0024, 0x2000, 0x0000, 0x0003, 0x91c8, 0xb182, 0x1b0c, 0x6cf6, 0x0024, + 0x0000, 0x0555, 0x2803, 0xc208, 0x0000, 0x0024, 0x3433, 0x0024, 0xf400, + 0x4511, 0x3110, 0x934c, 0x31f0, 0xd20c, 0x1fff, 0xfad5, 0x6dfe, 0x0024, + 0x3911, 0x8024, 0x39f1, 0xc024, 0x3480, 0x0024, 0x4080, 0x0024, 0x0000, + 0x0455, 0x2803, 0xa115, 0x0000, 0x0024, 0x3483, 0x184c, 0x1fff, 0xfb95, + 0x3410, 0x3804, 0x3480, 0x4024, 0x3473, 0x0024, 0x3443, 0x0024, 0x3410, + 0x8024, 0xfea2, 0x1243, 0x48ba, 0x3803, 0xfe86, 0x92cc, 0x51aa, 0x0024, + 0x44b2, 0x9bc4, 0x6fc6, 0x0024, 0x0000, 0x0595, 0x2803, 0xa118, 0x0000, + 0x0024, 0x3483, 0x0024, 0x1fff, 0xfa95, 0x3480, 0x0024, 0x4080, 0x0024, + 0x0005, 0xffd1, 0x2803, 0xa105, 0x3100, 0x0024, 0x4080, 0x4510, 0x0000, + 0x0595, 0x2803, 0xa115, 0x0000, 0x0024, 0x3613, 0x120c, 0x1fff, 0xfa95, + 0x3009, 0x3811, 0x0000, 0x0591, 0x3083, 0x1bd1, 0x3000, 0x07cc, 0x4090, + 0x0024, 0x3800, 0x0024, 0x3480, 0x0024, 0x4080, 0x4510, 0x3100, 0x0024, + 0x2803, 0xa105, 0x4080, 0x0024, 0x0000, 0x0595, 0x2803, 0x9d05, 0x0000, + 0x0024, 0x0000, 0x0455, 0x0000, 0x0142, 0x0004, 0x0010, 0x3613, 0x120c, + 0x1fff, 0xfb95, 0x3410, 0x3812, 0x0008, 0x0012, 0x3480, 0x4024, 0x0000, + 0x0555, 0xf1c2, 0x120c, 0x1fff, 0xfad5, 0x0006, 0x8081, 0x3480, 0xc024, + 0xff34, 0x0024, 0x48b6, 0x0024, 0x4122, 0x0024, 0x0000, 0x0142, 0x2901, + 0x9fc0, 0xf400, 0x4051, 0x000d, 0x0012, 0x0008, 0x0010, 0x0000, 0x0455, + 0x3483, 0x0024, 0x1fff, 0xfb95, 0x3410, 0x0024, 0x3480, 0x4024, 0x0000, + 0x0555, 0xf1c2, 0x120c, 0x1fff, 0xfad5, 0x0006, 0x8301, 0x3480, 0xc024, + 0xff34, 0x0024, 0x48b6, 0x0024, 0x4122, 0x0024, 0x2901, 0xce80, 0xf400, + 0x4051, 0x000d, 0x0010, 0x0000, 0x0143, 0x0000, 0x0455, 0x3483, 0x0024, + 0x1fff, 0xfb95, 0x3410, 0x0024, 0x3480, 0x4024, 0x0000, 0x0555, 0xf1c2, + 0x120c, 0x1fff, 0xfad5, 0xf1c2, 0x1202, 0x0002, 0x0001, 0x4122, 0x0024, + 0x4122, 0x0024, 0xff26, 0x4052, 0x0006, 0x8581, 0x48b6, 0x0024, 0x4122, + 0x0024, 0x2901, 0xdd00, 0xf400, 0x4051, 0xf400, 0x4510, 0x0000, 0x0551, + 0x3083, 0x1bd2, 0x3000, 0x0024, 0x6090, 0x0024, 0x0000, 0x0555, 0x0000, + 0x0041, 0x3800, 0x120c, 0x1fff, 0xfad5, 0x3480, 0x0024, 0xfe02, 0x11cc, + 0x48b2, 0x110c, 0x3411, 0x8024, 0x3491, 0xc024, 0x6cf6, 0x12cc, 0x0006, + 0x8050, 0x2803, 0x8e08, 0x0000, 0x0024, 0x0000, 0x8001, 0x3000, 0x984c, + 0x6122, 0x930c, 0x6810, 0x0024, 0x3e10, 0x0024, 0x0002, 0x0000, 0x4020, + 0x0024, 0x4020, 0x0024, 0x4020, 0x0024, 0x4020, 0x0024, 0x3e10, 0x0024, + 0x3440, 0x0024, 0xf400, 0x4011, 0x3e00, 0x054c, 0x3102, 0x0024, 0x2000, + 0x0000, 0x0003, 0xb7c8, 0x0000, 0x0455, 0x0000, 0x00c2, 0xb880, 0x920c, + 0x1fff, 0xfb95, 0x3800, 0x1b4c, 0x3410, 0x0024, 0x3480, 0x4024, 0xac22, + 0x4513, 0x3373, 0x0024, 0x3373, 0x0024, 0x3353, 0x0024, 0x3310, 0x8024, + 0x33f0, 0xc024, 0x6dc2, 0x0024, 0x3b10, 0x0024, 0x3bf0, 0x4024, 0x0000, + 0x04d5, 0x3483, 0x0024, 0x1fff, 0xfb15, 0x3410, 0x0024, 0x3480, 0x4024, + 0x4c82, 0x0024, 0x0000, 0x0024, 0x2803, 0xc209, 0x0000, 0x0024, 0x3433, + 0x0024, 0x3410, 0x0024, 0x34c0, 0x4024, 0x4c82, 0x0024, 0x0000, 0x0024, + 0x2803, 0xc209, 0x0000, 0x0024, 0x34c3, 0x0024, 0x3444, 0x0024, 0x3073, + 0x0024, 0x3063, 0x0024, 0x3000, 0x0024, 0x4080, 0x0024, 0x0000, 0x0591, + 0x2803, 0x50c5, 0x0000, 0x0455, 0x2803, 0xd9c0, 0xb880, 0x0024, 0x6890, + 0x184c, 0x3e10, 0x104c, 0xb880, 0x0024, 0x3e10, 0x0024, 0xf400, 0x4500, + 0x3e10, 0x12cc, 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, + 0x0024, 0x2000, 0x0000, 0x0003, 0xc588, 0x36c3, 0x10cc, 0xf400, 0x4511, + 0x3110, 0x934c, 0x31f0, 0xc024, 0x4d96, 0x0024, 0x3910, 0x8024, 0x39f0, + 0xc024, 0x3433, 0x184c, 0x3410, 0x0024, 0x34c0, 0x4024, 0x4c82, 0x0024, + 0x0000, 0x0040, 0x2803, 0xc2d5, 0x0000, 0x0024, 0x0000, 0x0100, 0x3e10, + 0x104c, 0xb880, 0x0024, 0x3e10, 0x0024, 0xf400, 0x4500, 0x3e10, 0x12cc, + 0x3440, 0x0024, 0xf400, 0x4010, 0x3e00, 0x004c, 0x3002, 0x0024, 0x2000, + 0x0000, 0x0003, 0xcc08, 0x0000, 0x0101, 0x6012, 0x094c, 0x3200, 0x1b0c, + 0x2803, 0xcdc1, 0x3073, 0x0024, 0x2803, 0xd9c0, 0x4480, 0x0024, 0x4080, + 0x014c, 0x3070, 0x0024, 0x2803, 0xcfd5, 0x0000, 0x0024, 0x4080, 0x01cc, + 0x0000, 0x0024, 0x2803, 0x2885, 0x3053, 0x0024, 0x32b0, 0x024c, 0x3009, + 0x024c, 0x4080, 0x02cc, 0x0000, 0x0024, 0x2803, 0xd605, 0x0000, 0x0024, + 0x34b3, 0x0024, 0x3450, 0x0024, 0x4080, 0x0024, 0x0000, 0x0184, 0x2803, + 0xd605, 0x0006, 0x0ec0, 0x34b3, 0x0024, 0x3454, 0x0024, 0x2803, 0xd600, + 0x3800, 0x0024, 0x6898, 0x12cc, 0x3450, 0x0024, 0x4080, 0x0024, 0x0006, + 0x1440, 0x2803, 0xd605, 0x0000, 0x0024, 0x34b3, 0x0024, 0x3454, 0x0024, + 0x3800, 0x0024, 0x34c3, 0x0024, 0x3404, 0x0024, 0x3073, 0x0024, 0x3063, + 0x0024, 0x3000, 0x0024, 0x4080, 0x1110, 0x0000, 0x0000, 0x2803, 0xd945, + 0x3073, 0x0024, 0x0000, 0x0144, 0x34c3, 0x0024, 0x3444, 0x0024, 0x3073, + 0x0024, 0x3063, 0x0024, 0x4480, 0x2000, 0x36f4, 0xc024, 0x36f4, 0x5812, + 0x36f1, 0xd810, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0xb386, 0x40d7, 0x4284, 0x184c, 0x0000, 0x05c0, 0x2803, 0xde15, 0xf5d8, + 0x3804, 0x0000, 0x0984, 0x6400, 0xb84a, 0x3e13, 0xf80d, 0xa204, 0x380e, + 0x0000, 0x800a, 0x0000, 0x00ce, 0x2403, 0xe14e, 0xffa4, 0x0024, 0x48b6, + 0x0024, 0x0000, 0x0024, 0x2803, 0xe144, 0x4000, 0x40c2, 0x4224, 0x0024, + 0x6090, 0x0024, 0xffa4, 0x0024, 0x0fff, 0xfe83, 0xfe86, 0x1bce, 0x36f3, + 0xd80d, 0x48b6, 0x0024, 0x0fff, 0xff03, 0xa230, 0x45c3, 0x2000, 0x0000, + 0x36f1, 0x180a, 0x0007, 0x0001, /*copy 1*/ + 0x802e, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x6a00, 0x0007, 0x0001, /*copy 1*/ + 0x8030, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x1b40, 0x0007, 0x0001, /*copy 1*/ + 0x8028, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x144e, 0x0007, 0x0001, /*copy 1*/ + 0x8032, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x7280, 0x0007, 0x0001, /*copy 1*/ + 0x3580, 0x0006, 0x8038, 0x0000, /*Rle(56)*/ + 0x0007, 0x0001, /*copy 1*/ + 0xfab3, 0x0006, 0x0254, /*copy 596*/ + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0xffff, 0xfffe, 0xfffb, 0xfff9, + 0xfff5, 0xfff2, 0xffed, 0xffe8, 0xffe3, 0xffde, 0xffd8, 0xffd3, 0xffce, + 0xffca, 0xffc7, 0xffc4, 0xffc4, 0xffc5, 0xffc7, 0xffcc, 0xffd3, 0xffdc, + 0xffe6, 0xfff3, 0x0001, 0x0010, 0x001f, 0x002f, 0x003f, 0x004e, 0x005b, + 0x0066, 0x006f, 0x0074, 0x0075, 0x0072, 0x006b, 0x005f, 0x004f, 0x003c, + 0x0024, 0x0009, 0xffed, 0xffcf, 0xffb0, 0xff93, 0xff77, 0xff5f, 0xff4c, + 0xff3d, 0xff35, 0xff34, 0xff3b, 0xff4a, 0xff60, 0xff7e, 0xffa2, 0xffcd, + 0xfffc, 0x002e, 0x0061, 0x0094, 0x00c4, 0x00f0, 0x0114, 0x0131, 0x0144, + 0x014b, 0x0146, 0x0134, 0x0116, 0x00eb, 0x00b5, 0x0075, 0x002c, 0xffde, + 0xff8e, 0xff3d, 0xfeef, 0xfea8, 0xfe6a, 0xfe39, 0xfe16, 0xfe05, 0xfe06, + 0xfe1b, 0xfe43, 0xfe7f, 0xfecd, 0xff2a, 0xff95, 0x0009, 0x0082, 0x00fd, + 0x0173, 0x01e1, 0x0242, 0x0292, 0x02cc, 0x02ec, 0x02f2, 0x02da, 0x02a5, + 0x0253, 0x01e7, 0x0162, 0x00c9, 0x0021, 0xff70, 0xfebc, 0xfe0c, 0xfd68, + 0xfcd5, 0xfc5b, 0xfc00, 0xfbc9, 0xfbb8, 0xfbd2, 0xfc16, 0xfc85, 0xfd1b, + 0xfdd6, 0xfeae, 0xff9e, 0x009c, 0x01a0, 0x02a1, 0x0392, 0x046c, 0x0523, + 0x05b0, 0x060a, 0x062c, 0x0613, 0x05bb, 0x0526, 0x0456, 0x0351, 0x021f, + 0x00c9, 0xff5a, 0xfde1, 0xfc6a, 0xfb05, 0xf9c0, 0xf8aa, 0xf7d0, 0xf73d, + 0xf6fa, 0xf70f, 0xf77e, 0xf848, 0xf96b, 0xfadf, 0xfc9a, 0xfe8f, 0x00ad, + 0x02e3, 0x051a, 0x073f, 0x0939, 0x0af4, 0x0c5a, 0x0d59, 0x0de1, 0x0de5, + 0x0d5c, 0x0c44, 0x0a9e, 0x0870, 0x05c7, 0x02b4, 0xff4e, 0xfbaf, 0xf7f8, + 0xf449, 0xf0c7, 0xed98, 0xeae0, 0xe8c4, 0xe765, 0xe6e3, 0xe756, 0xe8d2, + 0xeb67, 0xef19, 0xf3e9, 0xf9cd, 0x00b5, 0x088a, 0x112b, 0x1a72, 0x2435, + 0x2e42, 0x3866, 0x426b, 0x4c1b, 0x553e, 0x5da2, 0x6516, 0x6b6f, 0x7087, + 0x7441, 0x7686, 0x774a, 0x7686, 0x7441, 0x7087, 0x6b6f, 0x6516, 0x5da2, + 0x553e, 0x4c1b, 0x426b, 0x3866, 0x2e42, 0x2435, 0x1a72, 0x112b, 0x088a, + 0x00b5, 0xf9cd, 0xf3e9, 0xef19, 0xeb67, 0xe8d2, 0xe756, 0xe6e3, 0xe765, + 0xe8c4, 0xeae0, 0xed98, 0xf0c7, 0xf449, 0xf7f8, 0xfbaf, 0xff4e, 0x02b4, + 0x05c7, 0x0870, 0x0a9e, 0x0c44, 0x0d5c, 0x0de5, 0x0de1, 0x0d59, 0x0c5a, + 0x0af4, 0x0939, 0x073f, 0x051a, 0x02e3, 0x00ad, 0xfe8f, 0xfc9a, 0xfadf, + 0xf96b, 0xf848, 0xf77e, 0xf70f, 0xf6fa, 0xf73d, 0xf7d0, 0xf8aa, 0xf9c0, + 0xfb05, 0xfc6a, 0xfde1, 0xff5a, 0x00c9, 0x021f, 0x0351, 0x0456, 0x0526, + 0x05bb, 0x0613, 0x062c, 0x060a, 0x05b0, 0x0523, 0x046c, 0x0392, 0x02a1, + 0x01a0, 0x009c, 0xff9e, 0xfeae, 0xfdd6, 0xfd1b, 0xfc85, 0xfc16, 0xfbd2, + 0xfbb8, 0xfbc9, 0xfc00, 0xfc5b, 0xfcd5, 0xfd68, 0xfe0c, 0xfebc, 0xff70, + 0x0021, 0x00c9, 0x0162, 0x01e7, 0x0253, 0x02a5, 0x02da, 0x02f2, 0x02ec, + 0x02cc, 0x0292, 0x0242, 0x01e1, 0x0173, 0x00fd, 0x0082, 0x0009, 0xff95, + 0xff2a, 0xfecd, 0xfe7f, 0xfe43, 0xfe1b, 0xfe06, 0xfe05, 0xfe16, 0xfe39, + 0xfe6a, 0xfea8, 0xfeef, 0xff3d, 0xff8e, 0xffde, 0x002c, 0x0075, 0x00b5, + 0x00eb, 0x0116, 0x0134, 0x0146, 0x014b, 0x0144, 0x0131, 0x0114, 0x00f0, + 0x00c4, 0x0094, 0x0061, 0x002e, 0xfffc, 0xffcd, 0xffa2, 0xff7e, 0xff60, + 0xff4a, 0xff3b, 0xff34, 0xff35, 0xff3d, 0xff4c, 0xff5f, 0xff77, 0xff93, + 0xffb0, 0xffcf, 0xffed, 0x0009, 0x0024, 0x003c, 0x004f, 0x005f, 0x006b, + 0x0072, 0x0075, 0x0074, 0x006f, 0x0066, 0x005b, 0x004e, 0x003f, 0x002f, + 0x001f, 0x0010, 0x0001, 0xfff3, 0xffe6, 0xffdc, 0xffd3, 0xffcc, 0xffc7, + 0xffc5, 0xffc4, 0xffc4, 0xffc7, 0xffca, 0xffce, 0xffd3, 0xffd8, 0xffde, + 0xffe3, 0xffe8, 0xffed, 0xfff2, 0xfff5, 0xfff9, 0xfffb, 0xfffe, 0xffff, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0164, 0x04b9, 0x09a5, + 0x0d57, 0x045f, 0xe8cd, 0xbc5c, 0x9380, 0xa08d, 0x0c3f, 0x1d7a, 0x43d9, + 0x68b4, 0x7fff, 0x7fff, 0x68b4, 0x43d9, 0x1d7a, 0x0c3f, 0xa08d, 0x9380, + 0xbc5c, 0xe8cd, 0x045f, 0x0d57, 0x09a5, 0x04b9, 0x0164, 0xfd25, 0xfb12, + 0x1042, 0x253f, 0xd5bc, 0xed41, 0x08de, 0x53f7, 0x7fff, 0x53f7, 0x08de, + 0xed41, 0xd5bc, 0x253f, 0x1042, 0xfb12, 0xfd25, 0x0006, 0x0000, 0xfff7, + 0x0000, 0x0012, 0x0000, 0xffe4, 0x0000, 0x002e, 0x0000, 0xffbb, 0x0000, + 0x0067, 0x0000, 0xff6f, 0x0000, 0x00cb, 0x0000, 0xfeed, 0x0000, 0x0170, + 0x0000, 0xfe1d, 0x0000, 0x0274, 0x0000, 0xfcde, 0x0000, 0x03f8, 0x0000, + 0xfb0a, 0x0000, 0x0629, 0x0000, 0xf86c, 0x0000, 0x0943, 0x0000, 0xf4c1, + 0x0000, 0x0d9a, 0x0000, 0xef9e, 0x0000, 0x13b4, 0x0000, 0xe851, 0x0000, + 0x1c8a, 0x0000, 0xdd72, 0x0000, 0x2a3c, 0x0000, 0xcb94, 0x0000, 0x42bd, + 0x0000, 0xa75f, 0x0000, 0x7f22, 0x0000, 0xe516, 0x0000, 0x5168, 0x7fff, + 0x5168, 0x0000, 0xe516, 0x0000, 0x7f22, 0x0000, 0xa75f, 0x0000, 0x42bd, + 0x0000, 0xcb94, 0x0000, 0x2a3c, 0x0000, 0xdd72, 0x0000, 0x1c8a, 0x0000, + 0xe851, 0x0000, 0x13b4, 0x0000, 0xef9e, 0x0000, 0x0d9a, 0x0000, 0xf4c1, + 0x0000, 0x0943, 0x0000, 0xf86c, 0x0000, 0x0629, 0x0000, 0xfb0a, 0x0000, + 0x03f8, 0x0000, 0xfcde, 0x0000, 0x0274, 0x0000, 0xfe1d, 0x0000, 0x0170, + 0x0000, 0xfeed, 0x0000, 0x00cb, 0x0000, 0xff6f, 0x0000, 0x0067, 0x0000, + 0xffbb, 0x0000, 0x002e, 0x0000, 0xffe4, 0x0000, 0x0012, 0x0000, 0xfff7, + 0x0000, 0x0006, 0x0007, 0x0001, /*copy 1*/ + 0x180b, 0x0006, 0x0064, /*copy 100*/ + 0x000f, 0x0010, 0x001c, 0xfab3, 0x3580, 0x8037, 0xa037, 0x0001, 0x0000, + 0x3580, 0x01a4, 0x0046, 0x006f, 0x0072, 0x006d, 0x0061, 0x0074, 0x0020, + 0x004e, 0x006f, 0x0074, 0x0020, 0x0044, 0x0053, 0x0046, 0x002f, 0x0044, + 0x0046, 0x0046, 0x0000, 0x004f, 0x006b, 0x0000, 0x004e, 0x006f, 0x0074, + 0x0020, 0x0032, 0x0020, 0x0063, 0x0068, 0x0061, 0x006e, 0x006e, 0x0065, + 0x006c, 0x0073, 0x0000, 0x0049, 0x006e, 0x0076, 0x0061, 0x006c, 0x0069, + 0x0064, 0x0020, 0x0044, 0x0053, 0x0044, 0x0020, 0x0062, 0x0069, 0x0074, + 0x0073, 0x0074, 0x0072, 0x0065, 0x0061, 0x006d, 0x0000, 0x004e, 0x006f, + 0x0074, 0x0020, 0x0044, 0x0053, 0x0044, 0x0020, 0x0062, 0x0069, 0x0074, + 0x0073, 0x0074, 0x0072, 0x0065, 0x0061, 0x006d, 0x0000, 0xff2f, 0x0295, + 0x0a83, 0x16ef, 0x2912, 0x3215, 0x3215, 0x2912, 0x16ef, 0x0a83, 0x0295, + 0xff2f, 0x0007, 0x0001, /*copy 1*/ + 0x8025, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x5d8e, 0x0007, 0x0001, /*copy 1*/ + 0x1a00, 0x0006, 0x0020, /*copy 32*/ + 0x0046, 0x0046, 0x0055, 0x1a40, 0xfc57, 0x0000, 0x0000, 0x0055, 0x1a60, + 0xfc57, 0x0000, 0x0000, 0x0000, 0x1a80, 0xfc73, 0x0000, 0x0000, 0x0000, + 0x1aa0, 0xfc73, 0x0000, 0x0000, 0x0000, 0x3000, 0xfc84, 0x0000, 0x0000, + 0x0000, 0x3200, 0xfc84, 0x0000, 0x0000, 0x0007, 0x0001, /*copy 1*/ + 0x1a40, 0x0006, 0x8080, 0x0000, /*Rle(128)*/ + 0x000a, 0x0001, /*copy 1*/ + 0x0050, +#define PLUGIN_SIZE 8608 +#ifndef SKIP_PLUGIN_VARNAME +}; +#endif diff --git a/targets/esp32/components/VS1053/include/patches_flac.h b/targets/esp32/components/VS1053/include/patches_flac.h new file mode 100644 index 00000000..c74a87d1 --- /dev/null +++ b/targets/esp32/components/VS1053/include/patches_flac.h @@ -0,0 +1,961 @@ +#ifndef SKIP_PLUGIN_VARNAME +const unsigned short PLUGIN[] = { + /* Compressed plugin */ +#endif + 0x0007, 0x0001, /*copy 1*/ + 0x8050, 0x0006, 0x001e, /*copy 30*/ + 0x2a00, 0xc000, 0x3e12, 0xb817, 0x3e14, 0xf812, 0x3e01, 0xb811, 0x0007, + 0x9717, 0x0020, 0xffd2, 0x0030, 0x11d1, 0x3111, 0x8024, 0x3704, 0xc024, + 0x3b81, 0x8024, 0x3101, 0x8024, 0x3b81, 0x8024, 0x3f04, 0xc024, 0x2808, + 0x4800, 0x36f1, 0x9811, 0x0007, 0x0001, /*copy 1*/ + 0x8060, 0x0006, 0x0540, /*copy 1344*/ + 0xf400, 0x4095, 0x0000, 0x02c2, 0x6124, 0x0024, 0x0000, 0x0024, 0x2800, + 0x1ac5, 0x4192, 0x4542, 0x0000, 0x0041, 0x2000, 0x0015, 0x0030, 0x0317, + 0x2000, 0x0000, 0x3f00, 0x4024, 0x2000, 0x0000, 0x0000, 0x0000, 0x3e12, + 0x3800, 0x3e00, 0xb804, 0x0030, 0x0015, 0x0007, 0x8257, 0x3700, 0x984c, + 0xf224, 0x1444, 0xf224, 0x0024, 0x0008, 0x0002, 0x2910, 0x0181, 0x0000, + 0x1bc8, 0xb428, 0x1402, 0x0000, 0x8004, 0x2910, 0x0195, 0x0000, 0x1bc8, + 0xb428, 0x0024, 0x0006, 0x0095, 0x2800, 0x2945, 0x3e13, 0x780e, 0x3e11, + 0x7803, 0x3e13, 0xf806, 0x3e11, 0xf801, 0x3510, 0xb808, 0x003f, 0xe004, + 0xfec4, 0x3800, 0x48be, 0x17c3, 0xfec6, 0x41c2, 0x48be, 0x4497, 0x4090, + 0x1c46, 0xf06c, 0x0024, 0x2400, 0x2580, 0x6090, 0x41c3, 0x6628, 0x1c47, + 0x0000, 0x0024, 0x2800, 0x2449, 0xf07e, 0x0024, 0xf400, 0x4182, 0x673a, + 0x1c46, 0x0000, 0x0024, 0x2800, 0x2589, 0xf06c, 0x0024, 0xf400, 0x41c3, + 0x0000, 0x0024, 0x4224, 0x3442, 0x2903, 0xd9c0, 0x4336, 0x37c3, 0x0000, + 0x1805, 0x2903, 0xd9c0, 0x4508, 0x40c2, 0x450a, 0x9808, 0x0000, 0x0207, + 0xa478, 0x1bc0, 0xc45a, 0x1807, 0x0030, 0x03d5, 0x3d01, 0x5bc1, 0x36f3, + 0xd806, 0x3601, 0x5803, 0x36f3, 0x0024, 0x36f3, 0x580e, 0x0007, 0x8257, + 0x0000, 0x6004, 0x3730, 0x8024, 0xb244, 0x1c04, 0xd428, 0x3c02, 0x0006, + 0xc717, 0x2800, 0x2d05, 0x4284, 0x0024, 0x3613, 0x3c02, 0x0006, 0xc357, + 0x2901, 0x6ac0, 0x3e11, 0x5c05, 0x4284, 0x1bc5, 0x0007, 0x8257, 0x2800, + 0x3285, 0x0002, 0x0001, 0x3701, 0x0024, 0x0006, 0xc357, 0xb412, 0x9c02, + 0x002e, 0xe001, 0x2800, 0x3005, 0x6212, 0x0024, 0x0000, 0x0024, 0x2800, + 0x3295, 0x0000, 0x0024, 0x0030, 0x0117, 0x3f00, 0x0024, 0x3613, 0x0024, + 0x3e10, 0x3813, 0x3e14, 0x8024, 0x3e04, 0x8024, 0x2900, 0x4b40, 0x0006, + 0x02d3, 0x36e3, 0x0024, 0x3009, 0x1bd3, 0x0007, 0x8257, 0x3700, 0x8024, + 0xf224, 0x0024, 0x0000, 0x0024, 0x2800, 0x3491, 0x3600, 0x9844, 0x2900, + 0x3a40, 0x0000, 0x3508, 0x2911, 0xf140, 0x0000, 0x0024, 0x0030, 0x0057, + 0x3700, 0x0024, 0xf200, 0x4595, 0x0fff, 0xfe02, 0xa024, 0x164c, 0x8000, + 0x17cc, 0x3f00, 0x0024, 0x3500, 0x0024, 0x0021, 0x6d82, 0xd024, 0x44c0, + 0x0006, 0xa402, 0x2800, 0x3955, 0xd024, 0x0024, 0x0000, 0x0000, 0x2800, + 0x3955, 0x000b, 0x6d57, 0x3009, 0x3c00, 0x36f0, 0x8024, 0x36f2, 0x1800, + 0x2000, 0x0000, 0x0000, 0x0024, 0x3e14, 0x7810, 0x3e13, 0xb80d, 0x3e13, + 0xf80a, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0xf801, + 0x3e15, 0x3815, 0x0001, 0x000a, 0x0006, 0xc4d7, 0xbf8e, 0x9c42, 0x3e01, + 0x9c03, 0x0006, 0xa017, 0x0023, 0xffd1, 0x0007, 0x8250, 0x0fff, 0xfd85, + 0x3001, 0x0024, 0xa45a, 0x4494, 0x0000, 0x0093, 0x2800, 0x4091, 0xf25a, + 0x104c, 0x34f3, 0x0024, 0x2800, 0x4091, 0x0000, 0x0024, 0x3413, 0x084c, + 0x0000, 0x0095, 0x3281, 0xf806, 0x4091, 0x4d64, 0x2400, 0x42c0, 0x4efa, + 0x9c10, 0xf1eb, 0x6061, 0xfe55, 0x2f66, 0x5653, 0x4d64, 0x48b2, 0xa201, + 0x4efa, 0xa201, 0x36f3, 0x3c10, 0x36f5, 0x1815, 0x36f4, 0xd801, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0xd80a, 0x36f3, 0x980d, + 0x2000, 0x0000, 0x36f4, 0x5810, 0x36f3, 0x0024, 0x3009, 0x3848, 0x3e14, + 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, 0x2915, 0x94c0, + 0x0001, 0xcc11, 0x36f0, 0x0024, 0x2927, 0x9e40, 0x3604, 0x1811, 0x3613, + 0x0024, 0x3e14, 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, + 0x2915, 0x94c0, 0x0001, 0xcc11, 0x36f0, 0x0024, 0x36f4, 0x1811, 0x3009, + 0x1808, 0x2000, 0x0000, 0x0000, 0x190d, 0x3613, 0x0024, 0x3e22, 0xb815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e13, 0x7801, 0x3e10, + 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x3e14, 0xb813, + 0x3e03, 0xf80e, 0xb488, 0x44d5, 0x3543, 0x134c, 0x34e5, 0xc024, 0x3524, + 0x8024, 0x35a4, 0xc024, 0x3710, 0x8a0c, 0x3540, 0x4a0c, 0x3d44, 0x8024, + 0x3a10, 0x8024, 0x3590, 0x0024, 0x4010, 0x15c1, 0x6010, 0x3400, 0x3710, + 0x8024, 0x2800, 0x5704, 0x3af0, 0x8024, 0x3df0, 0x0024, 0x3591, 0x4024, + 0x3530, 0x4024, 0x4192, 0x4050, 0x6100, 0x1482, 0x4020, 0x1753, 0xbf8e, + 0x1582, 0x4294, 0x4011, 0xbd86, 0x408e, 0x2400, 0x550e, 0xfe6d, 0x2819, + 0x520e, 0x0a00, 0x5207, 0x2819, 0x4fbe, 0x0024, 0xad56, 0x904c, 0xaf5e, + 0x1010, 0xf7d4, 0x0024, 0xf7fc, 0x2042, 0x6498, 0x2046, 0x3cf4, 0x0024, + 0x3400, 0x170c, 0x4090, 0x1492, 0x35a4, 0xc024, 0x2800, 0x4f95, 0x3c00, + 0x0024, 0x4480, 0x914c, 0x36f3, 0xd80e, 0x36f4, 0x9813, 0x36f4, 0x1811, + 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0x5801, 0x3405, + 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x2814, 0x9c91, + 0x0000, 0x004d, 0x2814, 0x9940, 0x003f, 0x0013, 0x3e12, 0xb817, 0x3e12, + 0x7808, 0x3e11, 0xb811, 0x3e15, 0x7810, 0x3e18, 0xb823, 0x3e18, 0x3821, + 0x3e10, 0x3801, 0x48b2, 0x0024, 0x3e10, 0x3801, 0x3e11, 0x3802, 0x3009, + 0x3814, 0x0030, 0x0717, 0x3f05, 0xc024, 0x0030, 0x0351, 0x3100, 0x0024, + 0x4080, 0x0024, 0x0030, 0x10d1, 0x2800, 0x6745, 0x0001, 0x800a, 0x0006, + 0x6514, 0x3111, 0x8024, 0x6894, 0x13c1, 0x6618, 0x0024, 0xfe44, 0x1000, + 0x4cb2, 0x0406, 0x3c10, 0x0024, 0x3c50, 0x4024, 0x34f0, 0x4024, 0x661c, + 0x1040, 0xfe64, 0x0024, 0x4cb2, 0x0024, 0x3cf0, 0x4024, 0xbc82, 0x3080, + 0x0030, 0x0351, 0x3100, 0x8024, 0xfea8, 0x0024, 0x5ca2, 0x0024, 0x0000, + 0x0182, 0xac22, 0x0024, 0xf7c8, 0x0024, 0x48b2, 0x0024, 0xac22, 0x0024, + 0x2800, 0x6ac0, 0xf7cc, 0x1002, 0x0030, 0x0394, 0x3400, 0x4024, 0x3100, + 0x184c, 0x0006, 0xc051, 0x291e, 0x8080, 0x0006, 0x6410, 0x4088, 0x1001, + 0x0030, 0x1111, 0x3100, 0x184c, 0x0006, 0xc051, 0x291e, 0x8080, 0x0006, + 0x6550, 0x0006, 0x6694, 0x408c, 0x1002, 0xf224, 0x0024, 0x0006, 0xa017, + 0x2800, 0x6ed5, 0x0000, 0x0024, 0x2808, 0x3f41, 0x0006, 0x6410, 0x3050, + 0x0024, 0x3000, 0x4024, 0x6014, 0x0024, 0x0000, 0x0024, 0x2800, 0x6e19, + 0x0000, 0x0024, 0xf400, 0x4040, 0x38b0, 0x0024, 0x2808, 0x3f40, 0x3800, + 0x0024, 0x2800, 0x70c1, 0xf224, 0x0024, 0x0000, 0x0024, 0x2808, 0x3f45, + 0x4684, 0x4106, 0xf12c, 0x0024, 0xf148, 0x0024, 0x846c, 0x0024, 0x2808, + 0x3f40, 0xf400, 0x4184, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, + 0x3625, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, + 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x0006, 0xa090, 0x2912, 0x0d00, + 0x3e14, 0xc024, 0x4088, 0x8000, 0x4080, 0x0024, 0x0007, 0x90d1, 0x2800, + 0x7705, 0x0000, 0x0024, 0x0007, 0x9051, 0x3100, 0x4024, 0x4100, 0x0024, + 0x3900, 0x0024, 0x0007, 0x90d1, 0x0004, 0x0000, 0x31f0, 0x4024, 0x6014, + 0x0400, 0x0000, 0x0024, 0x2800, 0x7b51, 0x4080, 0x0024, 0x0000, 0x0000, + 0x2800, 0x7ac5, 0x0000, 0x0024, 0x0007, 0x9053, 0x3300, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0000, 0x2800, 0x7b58, 0x0000, 0x0024, 0x0007, 0x9051, + 0x3900, 0x0024, 0x3200, 0x504c, 0x6410, 0x0024, 0x3cf0, 0x0000, 0x4080, + 0x0024, 0x0006, 0xc691, 0x2800, 0x9405, 0x3009, 0x0400, 0x0007, 0x9051, + 0x0000, 0x1001, 0x3100, 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2800, + 0x8849, 0x003f, 0xe000, 0x0006, 0xc693, 0x3900, 0x0c00, 0x3009, 0x0001, + 0x6014, 0x0024, 0x0007, 0x1ad0, 0x2800, 0x8855, 0x3009, 0x0000, 0x4080, + 0x0024, 0x0000, 0x0301, 0x2800, 0x8245, 0x4090, 0x0024, 0x0000, 0x0024, + 0x2800, 0x8355, 0x0000, 0x0024, 0x3009, 0x0000, 0xc012, 0x0024, 0x2800, + 0x8840, 0x3009, 0x2001, 0x3009, 0x0000, 0x6012, 0x0024, 0x0000, 0x0341, + 0x2800, 0x8555, 0x0000, 0x0024, 0x6190, 0x0024, 0x2800, 0x8840, 0x3009, + 0x2000, 0x6012, 0x0024, 0x0000, 0x0381, 0x2800, 0x8715, 0x0000, 0x0024, + 0x6190, 0x0024, 0x2800, 0x8840, 0x3009, 0x2000, 0x6012, 0x0024, 0x0000, + 0x00c0, 0x2800, 0x8855, 0x0000, 0x0024, 0x3009, 0x2000, 0x0006, 0xa090, + 0x3009, 0x0000, 0x4080, 0x0024, 0x0000, 0x0081, 0x2800, 0x8d15, 0x0007, + 0x8c13, 0x3300, 0x104c, 0xb010, 0x0024, 0x0002, 0x8001, 0x2800, 0x8f85, + 0x34f0, 0x0024, 0x2800, 0x8d00, 0x0000, 0x0024, 0x0006, 0xc351, 0x3009, + 0x0000, 0x6090, 0x0024, 0x3009, 0x2000, 0x2900, 0x0b80, 0x3009, 0x0405, + 0x0006, 0xc690, 0x0006, 0xc6d1, 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, + 0x0024, 0x0006, 0xa093, 0x2800, 0x8b91, 0xb880, 0x0024, 0x2800, 0x9cc0, + 0x3009, 0x2c00, 0x4040, 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2800, + 0x9cd8, 0x0000, 0x0024, 0x0006, 0xc693, 0x3009, 0x0c00, 0x3009, 0x0001, + 0x6014, 0x0024, 0x0006, 0xc350, 0x2800, 0x9cc1, 0x0000, 0x0024, 0x6090, + 0x0024, 0x3009, 0x2c00, 0x3009, 0x0005, 0x2900, 0x0b80, 0x0000, 0x9cc8, + 0x3009, 0x0400, 0x4080, 0x0024, 0x0003, 0x8000, 0x2800, 0x9cc5, 0x0000, + 0x0024, 0x6400, 0x0024, 0x0000, 0x0081, 0x2800, 0x9cc9, 0x0000, 0x0024, + 0x0007, 0x8c13, 0x3300, 0x0024, 0xb010, 0x0024, 0x0006, 0xc650, 0x2800, + 0x9cd5, 0x0000, 0x0024, 0x0001, 0x0002, 0x3413, 0x0000, 0x3009, 0x0401, + 0x4010, 0x8406, 0x0000, 0x0281, 0xa010, 0x13c1, 0x4122, 0x0024, 0x0000, + 0x03c2, 0x6122, 0x8002, 0x462c, 0x0024, 0x469c, 0x0024, 0xfee2, 0x0024, + 0x48be, 0x0024, 0x6066, 0x8400, 0x0006, 0xc350, 0x2800, 0x9cc1, 0x0000, + 0x0024, 0x4090, 0x0024, 0x3009, 0x2400, 0x2900, 0x0b80, 0x3009, 0x0005, + 0x0007, 0x1b50, 0x2912, 0x0d00, 0x3613, 0x0024, 0x3a00, 0x0380, 0x4080, + 0x0024, 0x0000, 0x00c1, 0x2800, 0xa585, 0x3009, 0x0000, 0xb010, 0x008c, + 0x4192, 0x0024, 0x6012, 0x0024, 0x0006, 0xf051, 0x2800, 0xa398, 0x3009, + 0x0400, 0x0007, 0x1fd1, 0x30e3, 0x0400, 0x4080, 0x0024, 0x0000, 0x0301, + 0x2800, 0xa585, 0x3009, 0x0000, 0xb010, 0x0024, 0x0000, 0x0101, 0x6012, + 0x0024, 0x0006, 0xf051, 0x2800, 0xa595, 0x0000, 0x0024, 0x3023, 0x0400, + 0xf200, 0x184c, 0xb880, 0xa400, 0x3009, 0x2000, 0x3009, 0x0441, 0x3e10, + 0x4402, 0x2909, 0xa9c0, 0x3e10, 0x8024, 0x36e3, 0x0024, 0x36f4, 0xc024, + 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, + 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, + 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x0012, 0x5103, + 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x380d, 0x0030, 0x0250, 0x3e13, + 0xf80e, 0xbe8b, 0x83e0, 0x290c, 0x4840, 0x3613, 0x0024, 0x290c, 0x4840, + 0x4086, 0x984c, 0x0000, 0x00ce, 0x2400, 0xaf8e, 0x3009, 0x1bc0, 0x0000, + 0x01c3, 0xae3a, 0x184c, 0x0000, 0x0043, 0x3009, 0x3842, 0x290c, 0x4840, + 0x3009, 0x3840, 0x4084, 0x9bc0, 0xfe26, 0x9bc2, 0xceba, 0x0024, 0x4e8e, + 0x0024, 0x4e9a, 0x0024, 0x4f8e, 0x0024, 0x0000, 0x0102, 0x2800, 0xb4c5, + 0x0030, 0x0010, 0x0000, 0x0206, 0x3613, 0x0024, 0x290c, 0x4840, 0x3009, + 0x3840, 0x3000, 0xdbc0, 0xb366, 0x0024, 0x0000, 0x0024, 0x2800, 0xb4d5, + 0x4e8e, 0x0024, 0x4e9a, 0x0024, 0x4f8e, 0x0024, 0x0030, 0x0010, 0x2800, + 0xb195, 0x0000, 0x0206, 0x36f3, 0xd80e, 0x36f4, 0x180d, 0x36f1, 0x9807, + 0x36f1, 0x1805, 0x36f0, 0x9803, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, + 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3e10, 0xb812, 0x3e11, 0xb810, + 0x3e12, 0x0024, 0x0006, 0x9f92, 0x0025, 0xffd0, 0x3e04, 0x4bd1, 0x3181, + 0xf847, 0xb68c, 0x4440, 0x3009, 0x0802, 0x6024, 0x3806, 0x0006, 0x8a10, + 0x2903, 0xa905, 0x0000, 0xb948, 0x0000, 0x0800, 0x6101, 0x1602, 0xaf2e, + 0x0024, 0x4214, 0x1be3, 0xaf0e, 0x1811, 0x0fff, 0xfc00, 0xb200, 0x9bc7, + 0x0000, 0x03c0, 0x2800, 0xbd85, 0xb204, 0xa002, 0x2903, 0x6b00, 0x3613, + 0x2002, 0x4680, 0x1bc8, 0x36f1, 0x9810, 0x2000, 0x0000, 0x36f0, 0x9812, + 0x2a08, 0x1b8e, 0x2803, 0x8c80, 0x0000, 0xbe97, 0x0006, 0xd397, 0x2000, + 0x0000, 0x3f00, 0x0024, 0x0007, 0x0001, /*copy 1*/ + 0x8300, 0x0006, 0x191e, /*copy 6430*/ + 0x0030, 0x0055, 0xb080, 0x1402, 0x0fdf, 0xffc1, 0x0007, 0x9257, 0xb212, + 0x3c00, 0x3d00, 0x4024, 0x0006, 0x0097, 0x3f10, 0x0024, 0x3f00, 0x0024, + 0x0030, 0x0297, 0x3f00, 0x0024, 0x0007, 0x9017, 0x3f00, 0x0024, 0x0007, + 0x81d7, 0x3f10, 0x0024, 0xc090, 0x3c00, 0x0006, 0x0297, 0xb080, 0x3c00, + 0x0000, 0x0401, 0x000a, 0x1055, 0x0006, 0x0017, 0x3f10, 0x3401, 0x000a, + 0x2795, 0x3f00, 0x3401, 0x0001, 0x6a97, 0xf400, 0x55c0, 0x0000, 0x0817, + 0xb080, 0x57c0, 0x0014, 0x958f, 0x0000, 0x5b4e, 0x0030, 0x0017, 0x3700, + 0x0024, 0x0004, 0x0001, 0xb012, 0x0024, 0x0000, 0x004d, 0x280f, 0xe115, + 0x0006, 0x2016, 0x0006, 0x01d7, 0x3f00, 0x0024, 0x0000, 0x190d, 0x000f, + 0xf94f, 0x0000, 0xcd0e, 0x280f, 0xe100, 0x0006, 0x2016, 0x0000, 0x0080, + 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, + 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0007, 0x8a57, 0x3700, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0040, 0x2800, 0xced5, 0x0006, 0xa2d7, 0x3009, + 0x3c00, 0x0006, 0xa157, 0x3009, 0x1c00, 0x0006, 0x01d7, 0x0000, 0x190d, + 0x000a, 0x708f, 0x0000, 0xd7ce, 0x290b, 0x1a80, 0x3f00, 0x184c, 0x0030, + 0x0017, 0x4080, 0x1c01, 0x0000, 0x0200, 0x2800, 0xcb15, 0xb102, 0x0024, + 0x0000, 0xcd08, 0x2800, 0xcb15, 0x0000, 0xd3ce, 0x0011, 0x210f, 0x0000, + 0x190d, 0x280f, 0xcb00, 0x3613, 0x0024, 0x0006, 0xa115, 0x0006, 0x01d7, + 0x37f0, 0x1401, 0x6100, 0x1c01, 0x4012, 0x0024, 0x0000, 0x8000, 0x6010, + 0x0024, 0x34f3, 0x0400, 0x2800, 0xd698, 0x0000, 0x0024, 0x0000, 0x8001, + 0x6010, 0x3c01, 0x0000, 0x000d, 0x2811, 0x8259, 0x0000, 0x0024, 0x2a11, + 0x2100, 0x0030, 0x0257, 0x3700, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2800, 0xd9d5, 0x0006, 0x0197, 0x0006, 0xa115, 0x3f00, 0x3400, 0x003f, + 0xc000, 0xb600, 0x41c1, 0x0012, 0x5103, 0x000c, 0xc002, 0xdcd6, 0x0024, + 0x0019, 0xd4c2, 0x2800, 0xa845, 0x0001, 0x1188, 0x0013, 0xd9c3, 0x6fd6, + 0x0024, 0x0000, 0x190d, 0x2800, 0xdf95, 0x0014, 0x1b01, 0x0020, 0x480f, + 0x0000, 0xde4e, 0x0000, 0x190d, 0x2820, 0x41c0, 0x0001, 0x1188, 0x0039, + 0x324f, 0x0001, 0x3e8e, 0x2820, 0x4a18, 0xb882, 0x0024, 0x2a20, 0x48c0, + 0x003f, 0xfd00, 0xb700, 0x0024, 0x003f, 0xf901, 0x6010, 0x0024, 0x0000, + 0x0024, 0x280a, 0xc505, 0x0000, 0x190d, 0x0014, 0x1b01, 0x0015, 0x59c0, + 0x6fc2, 0x0024, 0x0019, 0x9301, 0x2800, 0xe9d5, 0x0018, 0x50c0, 0x290c, + 0x4840, 0x3613, 0x0024, 0x290c, 0x4840, 0x4086, 0x184c, 0x0000, 0x18c2, + 0x6234, 0x0024, 0x0000, 0x1d02, 0x2800, 0xe5d5, 0x6234, 0x0024, 0x0030, + 0x0317, 0x2800, 0xeb40, 0x3f00, 0x0024, 0x0000, 0x1d82, 0x2800, 0xe855, + 0x6234, 0x0024, 0x2912, 0x0d00, 0x4084, 0x184c, 0xf200, 0x0024, 0x6200, + 0x0024, 0x0006, 0x0017, 0x2800, 0xe540, 0xb080, 0x3c40, 0x0000, 0x0202, + 0x2800, 0xeb55, 0xa024, 0x0024, 0xc020, 0x0024, 0x2800, 0xe540, 0x0030, + 0x02d7, 0x6fc2, 0x0024, 0x0000, 0x0024, 0x2800, 0xeb55, 0x0000, 0x0024, + 0x2803, 0x2240, 0x000a, 0xcac8, 0x000a, 0x8c8f, 0x0000, 0xec8e, 0x000c, + 0x0981, 0x280a, 0x71c0, 0x002c, 0x9d40, 0x000a, 0x708f, 0x0000, 0xd7ce, + 0x280a, 0xc0d5, 0x0012, 0x5182, 0x6fd6, 0x0024, 0x003f, 0xfd81, 0x280a, + 0x8e45, 0xb710, 0x0024, 0xb710, 0x0024, 0x003f, 0xfc01, 0x6012, 0x0024, + 0x0000, 0x0101, 0x2801, 0x0855, 0xffd2, 0x0024, 0x48b2, 0x0024, 0x4190, + 0x0024, 0x0000, 0x190d, 0x2801, 0x0855, 0x0030, 0x0250, 0xb880, 0x104c, + 0x3cf0, 0x0024, 0x0010, 0x5500, 0xb880, 0x23c0, 0xb882, 0x2000, 0x0007, + 0x8590, 0x2914, 0xbec0, 0x0000, 0x0440, 0x0007, 0x8b50, 0xb880, 0x0024, + 0x2920, 0x0100, 0x3800, 0x0024, 0x2920, 0x0000, 0x0006, 0x8a91, 0x0000, + 0x0800, 0xb880, 0xa440, 0x003f, 0xfd81, 0xb710, 0xa7c0, 0x003f, 0xfc01, + 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, 0x1195, 0x0000, 0x0024, 0xffe2, + 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, 0x1195, + 0x0000, 0x0024, 0x2912, 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, 0x0006, + 0x8a90, 0x2801, 0x1195, 0x0000, 0x01c2, 0xb886, 0x8040, 0x3613, 0x03c1, + 0xbcd2, 0x0024, 0x0030, 0x0011, 0x2800, 0xfe15, 0x003f, 0xff42, 0xb886, + 0x8040, 0x3009, 0x03c1, 0x0000, 0x0020, 0xac22, 0x0024, 0x0000, 0x0102, + 0x6cd2, 0x0024, 0x3e10, 0x0024, 0x2909, 0x8c80, 0x3e00, 0x4024, 0x36f3, + 0x0024, 0x3e11, 0x8024, 0x3e01, 0xc024, 0x2901, 0x3540, 0x0000, 0x0201, + 0xf400, 0x4512, 0x2900, 0x0c80, 0x3213, 0x1b8c, 0x3100, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0024, 0x2801, 0x1195, 0x0000, 0x0024, 0x291a, 0x8a40, + 0x0000, 0x0100, 0x2920, 0x0200, 0x3633, 0x0024, 0x2920, 0x0280, 0x0000, + 0x0401, 0x408e, 0x0024, 0x2920, 0x0280, 0x0000, 0x0401, 0x003f, 0xfd81, + 0xb710, 0x4006, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, + 0x1195, 0x0000, 0x0024, 0xffe2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, + 0x0000, 0x0024, 0x2801, 0x1195, 0x0000, 0x0024, 0x2912, 0x2d80, 0x0000, + 0x0780, 0x4080, 0x0024, 0x0000, 0x01c2, 0x2800, 0xfa05, 0x0006, 0x8a90, + 0x2a01, 0x1180, 0x2920, 0x0100, 0x0000, 0x0401, 0x0000, 0x0180, 0x2920, + 0x0200, 0x3613, 0x0024, 0x2920, 0x0280, 0x3613, 0x0024, 0x0000, 0x0401, + 0x2920, 0x0280, 0x4084, 0x984c, 0x0019, 0x9d01, 0x6212, 0x0024, 0x001e, + 0x5c01, 0x2801, 0x0cd5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x0ec5, + 0x0000, 0x0024, 0x001b, 0x5bc1, 0x6212, 0x0024, 0x001b, 0xdd81, 0x2801, + 0x1295, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x1295, 0x0000, 0x0024, + 0x0000, 0x004d, 0x000a, 0xbf4f, 0x280a, 0xb880, 0x0001, 0x0fce, 0x0020, + 0xfb4f, 0x0000, 0x190d, 0x0001, 0x16ce, 0x2920, 0xf440, 0x3009, 0x2bc1, + 0x291a, 0x8a40, 0x36e3, 0x0024, 0x0000, 0x190d, 0x000a, 0x708f, 0x280a, + 0xcac0, 0x0000, 0xd7ce, 0x0030, 0x0017, 0x3700, 0x4024, 0x0000, 0x0200, + 0xb102, 0x0024, 0x0000, 0x00c0, 0x2801, 0x15c5, 0x0005, 0x4f92, 0x2909, + 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, 0xa115, 0xb080, 0x0024, + 0x3f00, 0x3400, 0x0000, 0x190d, 0x000a, 0x708f, 0x280a, 0xc0c0, 0x0000, + 0xd7ce, 0x0000, 0x004d, 0x0020, 0xfe0f, 0x2820, 0xfb40, 0x0001, 0x17ce, + 0x2801, 0x1995, 0x3009, 0x1000, 0x6012, 0x93cc, 0x0000, 0x0024, 0x2801, + 0x3445, 0x0000, 0x0024, 0x3413, 0x0024, 0x34b0, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0200, 0x2801, 0x1c95, 0xb882, 0x0024, 0x3453, 0x0024, 0x3009, + 0x13c0, 0x4080, 0x0024, 0x0000, 0x0200, 0x2801, 0x3445, 0x0000, 0x0024, + 0xb882, 0x130c, 0x0000, 0x004d, 0x0021, 0x058f, 0x2821, 0x0340, 0x0001, + 0x1d8e, 0x2801, 0x2dd5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x2dd5, + 0x0000, 0x0024, 0x34c3, 0x184c, 0x3e13, 0xb80f, 0xf400, 0x4500, 0x0026, + 0x9dcf, 0x0001, 0x218e, 0x0000, 0xfa0d, 0x2926, 0x8e80, 0x3e10, 0x110c, + 0x36f3, 0x0024, 0x2801, 0x2dc0, 0x36f3, 0x980f, 0x001c, 0xdd00, 0x001c, + 0xd901, 0x6ec2, 0x0024, 0x001c, 0xdd00, 0x2801, 0x2495, 0x0018, 0xdbc1, + 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0xc640, 0x3e00, 0x13cc, 0x2801, + 0x2b80, 0x36f3, 0x0024, 0x6ec2, 0x0024, 0x003f, 0xc000, 0x2801, 0x2715, + 0x002a, 0x4001, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0xafc0, 0x3e00, + 0x13cc, 0x2801, 0x2b80, 0x36f3, 0x0024, 0xb400, 0x0024, 0xd100, 0x0024, + 0x0000, 0x0024, 0x2801, 0x2b85, 0x0000, 0x0024, 0x3613, 0x0024, 0x3e11, + 0x4024, 0x2926, 0x8540, 0x3e01, 0x0024, 0x4080, 0x1b8c, 0x0000, 0x0024, + 0x2801, 0x2b85, 0x0000, 0x0024, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, + 0x8e80, 0x3e10, 0x13cc, 0x36f3, 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, + 0x0000, 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, 0x3110, 0x8024, 0x2826, + 0xa8c4, 0x31f0, 0xc024, 0x2a26, 0xad00, 0x34c3, 0x184c, 0x3410, 0x8024, + 0x3430, 0xc024, 0x0000, 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, 0x0000, + 0x0024, 0x2801, 0x3454, 0x4d06, 0x0024, 0x0000, 0x0200, 0x2922, 0x1885, + 0x0001, 0x32c8, 0x0000, 0x0200, 0x3e10, 0x8024, 0x2921, 0xca80, 0x3e00, + 0xc024, 0x291a, 0x8a40, 0x0000, 0x0024, 0x2922, 0x1880, 0x36f3, 0x0024, + 0x0000, 0x004d, 0x0021, 0x0ecf, 0x2821, 0x0bc0, 0x0001, 0x33ce, 0x2801, + 0x16c0, 0x3c30, 0x4024, 0x0000, 0x190d, 0x0000, 0x458e, 0x2821, 0x0f80, + 0x0027, 0x9e0f, 0x0020, 0xcd4f, 0x2820, 0xc780, 0x0001, 0x360e, 0x0006, + 0xf017, 0x0000, 0x0015, 0xb070, 0xbc15, 0x0000, 0x458e, 0x0027, 0x9e0f, + 0x2820, 0xcd80, 0x0000, 0x190d, 0x3613, 0x0024, 0x3e10, 0xb803, 0x3e14, + 0x3811, 0x3e11, 0x3805, 0x3e00, 0x3801, 0x0007, 0xc390, 0x0006, 0xa011, + 0x3010, 0x0444, 0x3050, 0x4405, 0x6458, 0x0302, 0xff94, 0x4081, 0x0003, + 0xffc5, 0x48b6, 0x0024, 0xff82, 0x0024, 0x42b2, 0x0042, 0xb458, 0x0003, + 0x4cd6, 0x9801, 0xf248, 0x1bc0, 0xb58a, 0x0024, 0x6de6, 0x1804, 0x0006, + 0x0010, 0x3810, 0x9bc5, 0x3800, 0xc024, 0x36f4, 0x1811, 0x36f0, 0x9803, + 0x283e, 0x2d80, 0x0fff, 0xffc3, 0x2801, 0x4c40, 0x0000, 0x0024, 0x3413, + 0x0024, 0x2801, 0x4045, 0xf400, 0x4517, 0x2801, 0x4440, 0x6894, 0x13cc, + 0x37b0, 0x184c, 0x6090, 0x1d51, 0x0000, 0x0910, 0x3f00, 0x060c, 0x3100, + 0x4024, 0x6016, 0xb812, 0x000c, 0x8012, 0x2801, 0x42d1, 0xb884, 0x0024, + 0x6894, 0x3002, 0x0000, 0x028d, 0x003a, 0x5e0f, 0x0001, 0x544e, 0x2939, + 0xb0c0, 0x3e10, 0x93cc, 0x4084, 0x9bd2, 0x4282, 0x0024, 0x0000, 0x0040, + 0x2801, 0x4645, 0x4292, 0x130c, 0x3443, 0x0024, 0x2801, 0x4785, 0x000c, + 0x8390, 0x2a01, 0x4b00, 0x3444, 0x0024, 0x3073, 0x0024, 0xc090, 0x014c, + 0x2801, 0x4b00, 0x3800, 0x0024, 0x000c, 0x4113, 0xb880, 0x2380, 0x3304, + 0x4024, 0x3800, 0x05cc, 0xcc92, 0x05cc, 0x3910, 0x0024, 0x3910, 0x4024, + 0x000c, 0x8110, 0x3910, 0x0024, 0x39f0, 0x4024, 0x3810, 0x0024, 0x38d0, + 0x4024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x34c3, 0x0024, 0x3444, 0x0024, + 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, 0x0024, 0x4080, 0x0024, 0x0000, + 0x0024, 0x2839, 0x53d5, 0x4284, 0x0024, 0x3613, 0x0024, 0x2801, 0x4e45, + 0x6898, 0xb804, 0x0000, 0x0084, 0x293b, 0x1cc0, 0x3613, 0x0024, 0x000c, + 0x8117, 0x3711, 0x0024, 0x37d1, 0x4024, 0x4e8a, 0x0024, 0x0000, 0x0015, + 0x2801, 0x5105, 0xce9a, 0x0024, 0x3f11, 0x0024, 0x3f01, 0x4024, 0x000c, + 0x8197, 0x408a, 0x9bc4, 0x3f15, 0x4024, 0x2801, 0x5345, 0x4284, 0x3c15, + 0x6590, 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, 0x4284, 0x0024, 0x0000, + 0x0024, 0x2801, 0x3f18, 0x458a, 0x0024, 0x2a39, 0x53c0, 0x003e, 0x2d4f, + 0x283a, 0x5ed5, 0x0001, 0x37ce, 0x000c, 0x4653, 0x0000, 0x0246, 0xffac, + 0x0c01, 0x48be, 0x0024, 0x4162, 0x4546, 0x6642, 0x4055, 0x3501, 0x8024, + 0x0000, 0x0087, 0x667c, 0x4057, 0x000c, 0x41d5, 0x283a, 0x62d5, 0x3501, + 0x8024, 0x667c, 0x1c47, 0x3701, 0x8024, 0x283a, 0x62d5, 0xc67c, 0x0024, + 0x0000, 0x0024, 0x283a, 0x62c5, 0x0000, 0x0024, 0x2a3a, 0x5ec0, 0x3009, + 0x3851, 0x3e14, 0xf812, 0x3e12, 0xb817, 0x3e11, 0x8024, 0x0006, 0x0293, + 0x3301, 0x8024, 0x468c, 0x3804, 0x0006, 0xa057, 0x2801, 0x6044, 0x0006, + 0x0011, 0x469c, 0x0024, 0x3be1, 0x8024, 0x2801, 0x6055, 0x0006, 0xc392, + 0x3311, 0x0024, 0x33f1, 0x2844, 0x3009, 0x2bc4, 0x0030, 0x04d2, 0x3311, + 0x0024, 0x3a11, 0x0024, 0x3201, 0x8024, 0x003f, 0xfc04, 0xb64c, 0x0fc4, + 0xc648, 0x0024, 0x3a01, 0x0024, 0x3111, 0x1fd3, 0x6498, 0x07c6, 0x868c, + 0x2444, 0x0023, 0xffd2, 0x3901, 0x8e06, 0x0030, 0x0551, 0x3911, 0x8e06, + 0x3961, 0x9c44, 0xf400, 0x44c6, 0xd46c, 0x1bc4, 0x36f1, 0xbc13, 0x2801, + 0x69d5, 0x36f2, 0x9817, 0x002b, 0xffd2, 0x3383, 0x188c, 0x3e01, 0x8c06, + 0x0006, 0xa097, 0x3009, 0x1c12, 0x3213, 0x0024, 0x468c, 0xbc12, 0x002b, + 0xffd2, 0xf400, 0x4197, 0x2801, 0x66c4, 0x3713, 0x0024, 0x2801, 0x6705, + 0x37e3, 0x0024, 0x3009, 0x2c17, 0x3383, 0x0024, 0x3009, 0x0c06, 0x468c, + 0x4197, 0x0006, 0xa052, 0x2801, 0x6904, 0x3713, 0x2813, 0x2801, 0x6945, + 0x37e3, 0x0024, 0x3009, 0x2c17, 0x36f1, 0x8024, 0x36f2, 0x9817, 0x36f4, + 0xd812, 0x2100, 0x0000, 0x3904, 0x5bd1, 0x2a01, 0x5a0e, 0x3e11, 0x7804, + 0x0030, 0x0257, 0x3701, 0x0024, 0x0013, 0x4d05, 0xd45b, 0xe0e1, 0x0007, + 0xc795, 0x2801, 0x7155, 0x0fff, 0xff45, 0x3511, 0x184c, 0x4488, 0xb808, + 0x0006, 0x8a97, 0x2801, 0x7105, 0x3009, 0x1c40, 0x3511, 0x1fc1, 0x0000, + 0x0020, 0xac52, 0x1405, 0x6ce2, 0x0024, 0x0000, 0x0024, 0x2801, 0x7101, + 0x68c2, 0x0024, 0x291a, 0x8a40, 0x3e10, 0x0024, 0x2921, 0xca80, 0x3e00, + 0x4024, 0x36f3, 0x0024, 0x3009, 0x1bc8, 0x36f0, 0x1801, 0x3601, 0x5804, + 0x3e13, 0x780f, 0x3e13, 0xb808, 0x0008, 0x9b0f, 0x0001, 0x740e, 0x2908, + 0x9300, 0x0000, 0x004d, 0x36f3, 0x9808, 0x2000, 0x0000, 0x36f3, 0x580f, + 0x0007, 0x81d7, 0x3711, 0x8024, 0x3711, 0xc024, 0x3700, 0x0024, 0x0000, + 0x2001, 0xb012, 0x0024, 0x0034, 0x0000, 0x2801, 0x7985, 0x0000, 0x01c1, + 0x3700, 0x0024, 0x0002, 0x0001, 0xb012, 0x0024, 0x002e, 0xe001, 0x2801, + 0x7885, 0x6512, 0x0024, 0x0034, 0x0000, 0x2801, 0x7995, 0x0000, 0x01c1, + 0x0030, 0x0117, 0x3f00, 0x0024, 0x0014, 0xc000, 0x0000, 0x01c1, 0x4fce, + 0x0024, 0xffea, 0x0024, 0x48b6, 0x0024, 0x4384, 0x4097, 0xb886, 0x45c6, + 0xfede, 0x0024, 0x4db6, 0x0024, 0x466c, 0x0024, 0x0006, 0xc610, 0x8dd6, + 0x8007, 0x0000, 0x00c6, 0xff6e, 0x0024, 0x48b2, 0x0024, 0x0034, 0x2406, + 0xffee, 0x0024, 0x2914, 0xaa80, 0x40b2, 0x0024, 0xf1c6, 0x0024, 0xf1d6, + 0x0024, 0x0000, 0x0201, 0x8d86, 0x0024, 0x61de, 0x0024, 0x0006, 0xc612, + 0x2801, 0x8001, 0x0006, 0xc713, 0x4c86, 0x0024, 0x2912, 0x1180, 0x0006, + 0xc351, 0x0006, 0x0210, 0x2912, 0x0d00, 0x3810, 0x984c, 0xf200, 0x2043, + 0x2808, 0xa000, 0x3800, 0x0024, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, 0x0000, 0x800a, 0x3e10, 0x7802, + 0x3e14, 0x0024, 0x2900, 0xb740, 0x0000, 0x0201, 0x0000, 0x0601, 0x3413, + 0x184c, 0x2903, 0x7680, 0x3cf0, 0x0024, 0x3413, 0x184c, 0x3400, 0x3040, + 0x3009, 0x33c1, 0x0000, 0x1fc1, 0xb010, 0x0024, 0x6014, 0x9040, 0x0006, + 0x8010, 0x2801, 0x88d5, 0x0000, 0x0024, 0x34e3, 0x1bcc, 0x6890, 0x0024, + 0x2801, 0x8a80, 0xb880, 0x2000, 0x3e10, 0x1381, 0x2903, 0xb8c0, 0x3e00, + 0x4024, 0x003f, 0xfe41, 0x36e3, 0x104c, 0x34f0, 0x0024, 0xa010, 0x0024, + 0x36f4, 0x0024, 0x36f0, 0x5802, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, + 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, + 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, + 0xb804, 0x3e01, 0x534c, 0xbe8a, 0x10c0, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2801, 0x93c5, 0x0000, 0x0024, 0x2903, 0x7680, 0x4082, 0x184c, 0x4c8a, + 0x134c, 0x0000, 0x0001, 0x6890, 0x10c2, 0x4294, 0x0024, 0xac22, 0x0024, + 0xbec2, 0x0024, 0x0000, 0x0024, 0x2801, 0x93c5, 0x0000, 0x0024, 0x6890, + 0x134c, 0xb882, 0x10c2, 0xac22, 0x0024, 0x4c92, 0x0024, 0xdc92, 0x0024, + 0xceca, 0x0024, 0x4e82, 0x1bc5, 0x36f0, 0x9804, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3645, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, + 0x3e14, 0x104c, 0x2900, 0xb740, 0x0000, 0x0081, 0x4080, 0x3040, 0x0000, + 0x0101, 0x2801, 0x9ac5, 0x0000, 0x0024, 0x4090, 0x0024, 0x0006, 0x8050, + 0x2801, 0xaed5, 0x0000, 0x0024, 0x2900, 0xb740, 0x3613, 0x0024, 0xb880, + 0x3000, 0x2801, 0xac80, 0x3009, 0x3380, 0x2900, 0xb740, 0x4122, 0x10cc, + 0x3cf0, 0x0024, 0x3001, 0x0024, 0x3400, 0x0024, 0x6800, 0x0024, 0xa408, + 0x9040, 0x4080, 0x0024, 0x0000, 0x07c1, 0x2801, 0xa055, 0x6894, 0x1380, + 0x6894, 0x130c, 0x3460, 0x0024, 0x6408, 0x4481, 0x4102, 0x1380, 0xf400, + 0x4052, 0x0000, 0x07c1, 0x34f0, 0xc024, 0x6234, 0x0024, 0x6824, 0x0024, + 0xa122, 0x0024, 0x6014, 0x0024, 0x0000, 0x0141, 0x2801, 0xa755, 0x0000, + 0x0024, 0x2900, 0xb740, 0x3613, 0x0024, 0x2801, 0xa5c0, 0xb88a, 0x4002, + 0x2901, 0x8c40, 0x3e00, 0x8024, 0x4c8e, 0xa801, 0x0000, 0x0201, 0x3a10, + 0x1bcc, 0x3000, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, 0x2801, 0xab55, + 0x659a, 0x0024, 0x6540, 0x184c, 0x0030, 0x0010, 0x2801, 0xa348, 0x0000, + 0x0024, 0x2801, 0xab40, 0x36f3, 0x0024, 0x2801, 0xaa00, 0xb88a, 0x0024, + 0x2903, 0x3ec0, 0x34d0, 0x4024, 0x4c8f, 0xa0a1, 0x0000, 0x0201, 0x3000, + 0x084c, 0xb010, 0x0024, 0x0000, 0x0024, 0x2801, 0xab55, 0x659a, 0x0024, + 0x6540, 0x10cc, 0x0030, 0x0010, 0x2801, 0xa7c8, 0x0000, 0x0024, 0x34d3, + 0x0024, 0x3423, 0x0024, 0xf400, 0x4510, 0x3009, 0x1380, 0x6090, 0x0024, + 0x3009, 0x2000, 0x6892, 0x108c, 0x34f0, 0x9000, 0xa122, 0x984c, 0x6016, + 0x13c1, 0x0000, 0x0102, 0x2801, 0x9c08, 0x0006, 0x8150, 0x2801, 0xaf40, + 0x3009, 0x1bcc, 0x6890, 0x938c, 0x3800, 0x0024, 0x36f4, 0x0024, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb804, 0x3e11, 0xb807, 0x3e14, + 0x3811, 0x3e04, 0x934c, 0x3430, 0x0024, 0x4080, 0x0024, 0x0000, 0x0206, + 0x2801, 0xb845, 0x0006, 0x8151, 0x3101, 0x130c, 0xff0c, 0x1102, 0x6408, + 0x0024, 0x4204, 0x0024, 0xb882, 0x4092, 0x1005, 0xfe02, 0x48be, 0x0024, + 0x4264, 0x0024, 0x2903, 0xc540, 0xf400, 0x4090, 0x36f4, 0x8024, 0x36f4, + 0x1811, 0x36f1, 0x9807, 0x36f0, 0x9804, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3675, 0x0024, + 0x3643, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x0000, 0x0181, 0x3e10, + 0xb803, 0x3e11, 0x3806, 0x3e11, 0xf810, 0x3e14, 0x7812, 0x3e13, 0xf80e, + 0x2903, 0x47c0, 0x3e03, 0x4024, 0x2900, 0xb740, 0x4088, 0x184c, 0x3413, + 0x184c, 0x2900, 0xb740, 0x6892, 0x3040, 0x4080, 0x3040, 0x0000, 0x0000, + 0x2801, 0xc5c5, 0x0000, 0x0024, 0x6890, 0x0024, 0x2903, 0x47c0, 0x3cd0, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2801, 0xc615, 0x0000, 0x0024, + 0x3433, 0x0024, 0xf400, 0x4510, 0x34d0, 0x0024, 0x6090, 0x0024, 0x2903, + 0x47c0, 0x3800, 0x0024, 0x4080, 0x10cc, 0xf400, 0x4510, 0x2801, 0xc385, + 0x34d0, 0x0024, 0x2801, 0xc600, 0x0000, 0x0024, 0x3cd0, 0x0024, 0x3433, + 0x0024, 0x34a0, 0x0024, 0xf400, 0x4510, 0x3430, 0x4024, 0x6100, 0x0024, + 0x0000, 0x0341, 0x3840, 0x0024, 0x3000, 0x0024, 0x6012, 0x0024, 0x0006, + 0x0581, 0x2801, 0xe381, 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, + 0x2000, 0x0000, 0x0000, 0x0024, 0x34d3, 0x184c, 0x3430, 0x8024, 0x2901, + 0x8c40, 0x3e00, 0x8024, 0x36f3, 0x11cc, 0xb888, 0x104c, 0x3c10, 0x0024, + 0x3c90, 0x4024, 0x2801, 0xcf40, 0x34e3, 0x0024, 0x3411, 0x8024, 0x3491, + 0xc024, 0x4f82, 0x128c, 0x3400, 0x4024, 0x4142, 0x0024, 0xf400, 0x4050, + 0x3800, 0x0024, 0x3440, 0x4024, 0x4142, 0x0024, 0x6498, 0x4050, 0x3009, + 0x2007, 0x0006, 0x8150, 0x3000, 0x11cc, 0x6402, 0x104c, 0x0000, 0x0024, + 0x2801, 0xcc88, 0x0000, 0x0024, 0x3493, 0x0024, 0x2801, 0xff40, 0x34f3, + 0x0024, 0x2801, 0xd6c0, 0xb888, 0x0024, 0x3430, 0x8024, 0x2901, 0x8c40, + 0x3e00, 0x8024, 0x4c8e, 0x130c, 0x3400, 0x5bcc, 0x4142, 0x0024, 0xf400, + 0x4050, 0x3800, 0x0024, 0x3440, 0x4024, 0x4142, 0x0024, 0xf400, 0x4050, + 0x0000, 0x0201, 0x3009, 0x2007, 0x0030, 0x0010, 0x3000, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0024, 0x2801, 0xff55, 0x6498, 0x0024, 0x0006, 0x8150, + 0x3000, 0x134c, 0x6402, 0x984c, 0x0000, 0x0024, 0x2801, 0xd208, 0x0000, + 0x0024, 0x2801, 0xff40, 0x3433, 0x1bcc, 0x0000, 0x0201, 0xb888, 0x104c, + 0x3430, 0x184c, 0x6010, 0x0024, 0x6402, 0x3000, 0x0000, 0x0201, 0x2801, + 0xdf58, 0x0030, 0x0010, 0x4090, 0x124c, 0x2401, 0xde40, 0x0000, 0x0024, + 0x3430, 0x8024, 0x2901, 0x8c40, 0x3e00, 0x8024, 0x4c8e, 0x130c, 0x3400, + 0x4024, 0x4142, 0x0024, 0xf400, 0x4050, 0x3800, 0x0024, 0x3410, 0x4024, + 0x4142, 0x0024, 0x6498, 0x4050, 0x3009, 0x2007, 0x0030, 0x0010, 0x0000, + 0x0201, 0x3473, 0x0024, 0x3490, 0x0024, 0x3e00, 0x13cc, 0x2901, 0x9580, + 0x3444, 0x8024, 0x3000, 0x1bcc, 0xb010, 0x0024, 0x0000, 0x0024, 0x2801, + 0xff55, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3470, 0x0024, 0x3e10, 0x104c, + 0x34c0, 0x4024, 0x2901, 0xb1c0, 0x3e00, 0x4024, 0x2801, 0xff40, 0x36e3, + 0x0024, 0x0000, 0x0801, 0x3413, 0x0024, 0x34f0, 0x0024, 0x6012, 0x0024, + 0x0000, 0x07c1, 0x2801, 0xfe88, 0x0000, 0x0024, 0x6010, 0x114c, 0xb888, + 0x32c0, 0x6402, 0x0024, 0x0000, 0x0101, 0x2801, 0xeb18, 0x0000, 0x0024, + 0x4090, 0x134c, 0x2401, 0xea40, 0x3009, 0x184c, 0x3430, 0x8024, 0x2901, + 0x8c40, 0x3e00, 0x8024, 0x4c8e, 0x130c, 0x3400, 0x4024, 0x4142, 0x0024, + 0xf400, 0x4050, 0x3800, 0x0024, 0x3410, 0x4024, 0x4142, 0x0024, 0x6498, + 0x4050, 0x3009, 0x2007, 0x0000, 0x0101, 0x3433, 0x1bcc, 0x2900, 0xb740, + 0x3613, 0x0024, 0x0000, 0x0141, 0x6090, 0x118c, 0x2900, 0xb740, 0x3ca0, + 0x184c, 0x3473, 0x184c, 0xb888, 0x3380, 0x3400, 0x0024, 0x6402, 0x0024, + 0x0000, 0x0201, 0x2801, 0xf1d8, 0x0000, 0x0024, 0x4090, 0x104c, 0x2401, + 0xf100, 0x0000, 0x0024, 0x34a0, 0x8024, 0x2901, 0x8c40, 0x3e00, 0x8024, + 0x0006, 0x8002, 0x4244, 0x118c, 0x4244, 0x0024, 0x6498, 0x4095, 0x3009, + 0x3440, 0x3009, 0x37c1, 0x0000, 0x0201, 0x34f3, 0x0024, 0x0030, 0x0010, + 0x3490, 0x0024, 0x3e00, 0x138c, 0x2901, 0x9580, 0x3444, 0x8024, 0x3000, + 0x1bcc, 0xb010, 0x0024, 0x0000, 0x0024, 0x2801, 0xff55, 0x4112, 0x0024, + 0x3463, 0x0024, 0x34a0, 0x0024, 0x6012, 0x0024, 0x0006, 0x8111, 0x2801, + 0xfb19, 0x0000, 0x0024, 0x3100, 0x11cc, 0x3490, 0x4024, 0x4010, 0x0024, + 0x0000, 0x0a01, 0x6012, 0x0024, 0x0006, 0x8151, 0x2801, 0xfb18, 0x0000, + 0x0024, 0x3613, 0x114c, 0x3101, 0x3804, 0x3490, 0x8024, 0x6428, 0x138c, + 0x3470, 0x8024, 0x3423, 0x0024, 0x3420, 0xc024, 0x4234, 0x1241, 0x4380, + 0x4092, 0x2903, 0xc540, 0x0006, 0x8010, 0x2801, 0xff40, 0x3009, 0x1bcc, + 0x0006, 0x8151, 0x3613, 0x114c, 0x3101, 0x3804, 0x3490, 0x8024, 0x6428, + 0x138c, 0x3470, 0x8024, 0x3423, 0x0024, 0x3420, 0xc024, 0x4234, 0x1241, + 0x4380, 0x4092, 0x2903, 0xcf00, 0x0006, 0x8010, 0x2801, 0xff40, 0x3009, + 0x1bcc, 0x0006, 0x8050, 0x6890, 0x0024, 0x3800, 0x0024, 0x3433, 0x0024, + 0x34d0, 0x0024, 0x4080, 0x0024, 0x0006, 0x8150, 0x2802, 0x04c5, 0x0000, + 0x0024, 0x3000, 0x11cc, 0xb888, 0x10cc, 0x6402, 0x3240, 0x3493, 0x0024, + 0x3444, 0x8024, 0x2802, 0x04d8, 0x4090, 0x0024, 0x2402, 0x0480, 0x0000, + 0x0024, 0x6499, 0x2620, 0xb78e, 0x4001, 0x0000, 0x0000, 0x3433, 0x0024, + 0xcfce, 0x1340, 0xaf0e, 0x0024, 0x3a11, 0xa807, 0x36f3, 0x4024, 0x36f3, + 0xd80e, 0x36f4, 0x5812, 0x36f1, 0xd810, 0x36f1, 0x1806, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, + 0xf804, 0x0000, 0x3fc3, 0x3e11, 0x7806, 0x3e11, 0xf810, 0xbc82, 0x12cc, + 0x3404, 0x0024, 0x3023, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x3454, + 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x2900, 0xb740, 0x0000, 0x0201, + 0x0006, 0x9301, 0x4088, 0x134c, 0x3400, 0x8024, 0xd204, 0x0024, 0xb234, + 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x3500, 0x0024, 0x3c30, 0x0024, + 0x0000, 0x2000, 0xb400, 0x0024, 0x0000, 0x3001, 0x2802, 0x1255, 0x0000, + 0x3800, 0x0000, 0x0041, 0xfe42, 0x12cc, 0x48b2, 0x1090, 0x3810, 0x0024, + 0x38f0, 0x4024, 0x2802, 0x3340, 0x3430, 0x0024, 0xb400, 0x0024, 0x6012, + 0x0024, 0x0000, 0x3801, 0x2802, 0x1595, 0x0000, 0x3c00, 0x0000, 0x07c0, + 0x0000, 0x0041, 0xb400, 0x12cc, 0xfe02, 0x1150, 0x48b2, 0x0024, 0x689a, + 0x2040, 0x2802, 0x3200, 0x38f0, 0x4024, 0xb400, 0x0024, 0x6012, 0x0024, + 0x0000, 0x3c01, 0x2802, 0x1915, 0x0000, 0x3e00, 0x0000, 0x03c0, 0x0000, + 0x0085, 0x4592, 0x12cc, 0xb400, 0x1150, 0xfe02, 0x0024, 0x48b2, 0x0024, + 0x3810, 0x0024, 0x2802, 0x3200, 0x38f0, 0x4024, 0xb400, 0x0024, 0x6012, + 0x0024, 0x0000, 0x3e01, 0x2802, 0x1c95, 0x0000, 0x3f00, 0x0000, 0x01c0, + 0xf20a, 0x12cc, 0xb400, 0x1150, 0xf252, 0x0024, 0xfe02, 0x0024, 0x48b2, + 0x0024, 0x3810, 0x0024, 0x2802, 0x3200, 0x38f0, 0x4024, 0xb400, 0x130c, + 0x6012, 0x0024, 0x0000, 0x3f01, 0x2802, 0x2015, 0x4390, 0x0024, 0x0000, + 0x0041, 0x0000, 0x0105, 0x4590, 0x13cc, 0xb400, 0x1150, 0xfe02, 0x0024, + 0x48b2, 0x0024, 0x3810, 0x0024, 0x2802, 0x3200, 0x38f0, 0x4024, 0xb400, + 0x0024, 0x6012, 0x1100, 0x0000, 0x01c1, 0x2802, 0x2395, 0x0000, 0x0024, + 0x0000, 0x0041, 0x0000, 0x0145, 0x6890, 0x12cc, 0xb400, 0x1150, 0xfe02, + 0x0024, 0x48b2, 0x0024, 0x3810, 0x0024, 0x2802, 0x3200, 0x38f0, 0x4024, + 0x6012, 0x0024, 0x0000, 0x3f81, 0x2802, 0x2615, 0xb430, 0x0024, 0x6012, + 0x0024, 0x0000, 0x0024, 0x2802, 0x2615, 0x0000, 0x0024, 0x2802, 0x3200, + 0x0000, 0x0185, 0x2802, 0x3340, 0xc890, 0x0024, 0x0000, 0x3fc3, 0x0000, + 0x0201, 0x34d3, 0x0024, 0x2900, 0xb740, 0x3433, 0x184c, 0x0006, 0x9301, + 0x4088, 0x134c, 0x3400, 0x8024, 0xd204, 0x0024, 0xb234, 0x0024, 0x4122, + 0x0024, 0xf400, 0x4055, 0x0000, 0x2001, 0x3500, 0x0024, 0x3c30, 0x0024, + 0x0000, 0x3000, 0xb400, 0x0024, 0x6012, 0x0024, 0x0000, 0x0182, 0x2802, + 0x2c45, 0x0000, 0x0024, 0x2802, 0x3340, 0xc890, 0x0024, 0x459a, 0x12cc, + 0x3404, 0x0024, 0x3023, 0x0024, 0x3010, 0x0024, 0x30d0, 0x4024, 0xac22, + 0x0046, 0x003f, 0xf982, 0x3011, 0xc024, 0x0000, 0x0023, 0xaf2e, 0x0024, + 0x0000, 0x0182, 0xccf2, 0x0024, 0x0000, 0x0fc6, 0x0000, 0x0047, 0xb46c, + 0x2040, 0xfe6e, 0x23c1, 0x3454, 0x0024, 0x3010, 0x0024, 0x30f0, 0x4024, + 0xac22, 0x0024, 0xccb2, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x458a, + 0x134c, 0x0000, 0x0201, 0x2802, 0x2755, 0x0000, 0x3fc3, 0x3430, 0x0024, + 0x36f1, 0xd810, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3675, + 0x0024, 0x3633, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, + 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x3e14, 0xb813, 0x3e13, + 0xf80e, 0x3e03, 0x4024, 0x2903, 0xac40, 0x0000, 0x0381, 0x000f, 0xff81, + 0x6012, 0x184c, 0x0000, 0x0201, 0x2802, 0x3bc5, 0x0000, 0x0024, 0x2900, + 0xb740, 0x0003, 0x1f08, 0x3613, 0x0024, 0x0000, 0x0401, 0x0006, 0x8a10, + 0x2900, 0xbf40, 0xb880, 0x1bcc, 0xb880, 0x11cc, 0x3413, 0x184c, 0x3c90, + 0x0024, 0x2900, 0xb740, 0x34f3, 0x0024, 0x3473, 0x184c, 0x3c00, 0x0000, + 0x4080, 0x0024, 0x0006, 0x9301, 0x2802, 0x4145, 0x003f, 0xfe04, 0x3490, + 0x8024, 0xa244, 0x0024, 0x2903, 0x8f40, 0xb880, 0x0024, 0x2900, 0xbf40, + 0x003f, 0xfe04, 0x3473, 0x184c, 0x0006, 0x8091, 0x3413, 0x0024, 0x34f0, + 0x8024, 0x3400, 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, 0x3fc3, + 0xb234, 0x0024, 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, 0x3500, + 0x0024, 0xd024, 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, 0x6892, 0x4055, + 0x3500, 0x0024, 0x3cf0, 0x0024, 0x34a0, 0x0024, 0xf100, 0x0024, 0xb010, + 0x0024, 0x3c60, 0x0024, 0x34b0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0201, + 0x2900, 0xb740, 0x3ce0, 0x0024, 0x0006, 0x9301, 0x3473, 0x184c, 0x3c10, + 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, 0x0024, 0x0000, 0x3fc3, + 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x003f, 0xff01, 0x3500, + 0x0024, 0x3cf0, 0x0024, 0x34c0, 0x0024, 0xa010, 0x0024, 0x0000, 0x03c1, + 0x3c40, 0x0024, 0x34d0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0201, 0x2900, + 0xb740, 0x3cc0, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, 0x0024, + 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, 0x0024, 0x0000, 0x3fc3, 0xb234, + 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x003f, 0xff01, 0x3500, 0x0024, + 0x3cf0, 0x0024, 0x3400, 0x0024, 0xa010, 0x0024, 0x0000, 0x01c1, 0x3900, + 0x0024, 0x34e0, 0x0024, 0xf100, 0x0024, 0xb010, 0x0024, 0x6892, 0x3080, + 0x34f0, 0x0024, 0xb010, 0x0024, 0x3cb0, 0x0024, 0x3450, 0x0024, 0x34a0, + 0x4024, 0xc010, 0x0024, 0x0000, 0x0181, 0x2802, 0x55c5, 0x3100, 0x0024, + 0x6890, 0x07cc, 0x2803, 0x1f00, 0x3900, 0x0024, 0x6012, 0x0024, 0x0000, + 0x0201, 0x2802, 0x5758, 0x0000, 0x0024, 0x2802, 0x5a40, 0x6090, 0x044c, + 0x6012, 0x0024, 0x0000, 0x0281, 0x2802, 0x5988, 0x6012, 0x0024, 0x0000, + 0x0080, 0x2802, 0x5999, 0x0000, 0x0024, 0x2802, 0x5a40, 0x3113, 0x0024, + 0x6890, 0x07cc, 0x2803, 0x1f00, 0x3900, 0x0024, 0x0000, 0x0201, 0x3900, + 0x114c, 0x34b0, 0x0024, 0x6012, 0x0024, 0x0006, 0x08c1, 0x2802, 0x6481, + 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, 0x2000, 0x0000, 0x0000, + 0x0024, 0x2802, 0x6480, 0x0000, 0x0024, 0x0000, 0x0200, 0x0006, 0x8110, + 0x2802, 0x6480, 0x3800, 0x0024, 0x0000, 0x0300, 0x0006, 0x8110, 0x2802, + 0x6480, 0x3800, 0x0024, 0x0006, 0x8050, 0x6890, 0x0024, 0x2803, 0x1f00, + 0x3800, 0x0024, 0x0000, 0x0400, 0x0006, 0x8110, 0x2802, 0x6480, 0x3800, + 0x0024, 0x0000, 0x0500, 0x0006, 0x8110, 0x2802, 0x6480, 0x3800, 0x0024, + 0x0000, 0x0600, 0x0006, 0x8110, 0x2802, 0x6480, 0x3800, 0x0024, 0x0006, + 0x8050, 0x6890, 0x0024, 0x2803, 0x1f00, 0x3800, 0x0024, 0x3423, 0x184c, + 0x3460, 0x0024, 0x4080, 0x0024, 0x0006, 0x8200, 0x2802, 0x69c5, 0x3e10, + 0x0024, 0x0000, 0x01c0, 0x3e10, 0x0024, 0x3490, 0x0024, 0x2902, 0x07c0, + 0x3e00, 0x13cc, 0x36d3, 0x11cc, 0x3413, 0x0024, 0x4080, 0x3240, 0x34f3, + 0x0024, 0x2802, 0x6d98, 0x0000, 0x0024, 0x0006, 0x8010, 0x6890, 0x0024, + 0x2803, 0x1f00, 0x3800, 0x0024, 0x0000, 0x0180, 0x3e10, 0x0024, 0x3490, + 0x0024, 0x2902, 0x07c0, 0x3e00, 0x13cc, 0x36d3, 0x11cc, 0x3413, 0x0024, + 0x4080, 0x3240, 0x34f3, 0x0024, 0x2802, 0x6d98, 0x0000, 0x0024, 0x0006, + 0x8010, 0x6890, 0x0024, 0x2803, 0x1f00, 0x3800, 0x0024, 0x0000, 0x0201, + 0x3433, 0x0024, 0x34d0, 0x0024, 0x6012, 0x0024, 0x0006, 0x0ac1, 0x2802, + 0x7f81, 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, 0x2000, 0x0000, + 0x0000, 0x0024, 0x0006, 0x8050, 0x6890, 0x0024, 0x2803, 0x1f00, 0x3800, + 0x0024, 0x0000, 0x3000, 0x2802, 0x8140, 0x0006, 0x8150, 0x0000, 0x9000, + 0x0006, 0x8150, 0x3433, 0x0024, 0x34d0, 0x4024, 0x4192, 0x0024, 0x4192, + 0x0024, 0x2802, 0x8140, 0xa010, 0x0024, 0x0000, 0x0201, 0x0006, 0x8150, + 0x2900, 0xb740, 0x3613, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, + 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, 0x0024, 0x0000, 0x3fc3, + 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x3500, 0x0024, 0x3cf0, + 0x0024, 0x3490, 0x0024, 0x2802, 0x8140, 0x6090, 0x0024, 0x003f, 0xfe04, + 0x0000, 0x0401, 0x0006, 0x8150, 0x2900, 0xb740, 0x3613, 0x0024, 0x0006, + 0x9301, 0x3473, 0x0024, 0x3c10, 0x0024, 0x34f0, 0x8024, 0x3400, 0xc024, + 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, 0x3fc3, 0xb234, 0x0024, 0x4122, + 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, 0x3500, 0x0024, 0xd024, 0x3000, + 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x3500, 0x0024, 0x3cf0, + 0x0024, 0x3490, 0x0024, 0x2802, 0x8140, 0x6090, 0x0024, 0x0000, 0x4000, + 0x0000, 0x0202, 0x0006, 0x8150, 0x3433, 0x0024, 0x34d0, 0x4024, 0x6122, + 0x0024, 0xa010, 0x0024, 0x0004, 0x8001, 0x3800, 0x110c, 0x0006, 0x8150, + 0x3000, 0x0024, 0x6012, 0x1300, 0x0000, 0x0401, 0x2802, 0x8409, 0x0000, + 0x0024, 0x6890, 0x82cc, 0x2803, 0x1f00, 0x3800, 0x0024, 0x6012, 0x0024, + 0x0006, 0x0cc1, 0x2802, 0xab81, 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, + 0x0024, 0x2000, 0x0000, 0x0000, 0x0024, 0x2802, 0xab80, 0x0000, 0x0024, + 0x0016, 0x2200, 0x0006, 0x8190, 0x6892, 0x2040, 0x2802, 0xab80, 0x38f0, + 0x4024, 0x002c, 0x4400, 0x0000, 0x0081, 0x0006, 0x8190, 0x3810, 0x0024, + 0x2802, 0xab80, 0x38f0, 0x4024, 0x003b, 0x8000, 0x0000, 0x0081, 0x0006, + 0x8190, 0x3810, 0x0024, 0x2802, 0xab80, 0x38f0, 0x4024, 0x0007, 0xd000, + 0x0006, 0x8190, 0xb882, 0x2040, 0x2802, 0xab80, 0x38f0, 0x4024, 0x000f, + 0xa000, 0x0006, 0x8190, 0xb882, 0x2040, 0x2802, 0xab80, 0x38f0, 0x4024, + 0x0015, 0x8880, 0x0006, 0x8190, 0xb882, 0x2040, 0x2802, 0xab80, 0x38f0, + 0x4024, 0x0017, 0x7000, 0x0006, 0x8190, 0xb882, 0x2040, 0x2802, 0xab80, + 0x38f0, 0x4024, 0x001f, 0x4000, 0x0006, 0x8190, 0xb882, 0x2040, 0x2802, + 0xab80, 0x38f0, 0x4024, 0x002b, 0x1100, 0x0006, 0x8190, 0xb882, 0x2040, + 0x2802, 0xab80, 0x38f0, 0x4024, 0x002e, 0xe000, 0x0006, 0x8190, 0xb882, + 0x2040, 0x2802, 0xab80, 0x38f0, 0x4024, 0x001d, 0xc000, 0x0006, 0x8190, + 0x6892, 0x2040, 0x2802, 0xab80, 0x38f0, 0x4024, 0x0006, 0x8190, 0x0000, + 0x0201, 0x0000, 0xfa04, 0x2900, 0xb740, 0x3613, 0x0024, 0x0006, 0x9301, + 0xb88a, 0x11cc, 0x3c10, 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, + 0x0024, 0x0000, 0x3fc3, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, + 0x3500, 0x0024, 0x3cf0, 0x0024, 0x3490, 0x0024, 0xfe50, 0x4005, 0x48b2, + 0x0024, 0xfeca, 0x0024, 0x40b2, 0x0024, 0x3810, 0x0024, 0x2802, 0xab80, + 0x38f0, 0x4024, 0x003f, 0xfe04, 0x0000, 0x0401, 0x0006, 0x8190, 0x2900, + 0xb740, 0x3613, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, 0x0024, + 0x34f0, 0x8024, 0x3400, 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, + 0x3fc3, 0xb234, 0x0024, 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, + 0x3500, 0x0024, 0xd024, 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, + 0x4055, 0x0000, 0x0041, 0x3500, 0x0024, 0x3cf0, 0x0024, 0x3490, 0x0024, + 0xfe02, 0x0024, 0x48b2, 0x0024, 0x3810, 0x0024, 0x2802, 0xab80, 0x38f0, + 0x4024, 0x003f, 0xfe04, 0x0000, 0x0401, 0x0006, 0x8190, 0x2900, 0xb740, + 0x3613, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, 0x0024, 0x34f0, + 0x8024, 0x3400, 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, 0x3fc3, + 0xb234, 0x0024, 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, 0x3500, + 0x0024, 0xd024, 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, + 0x3500, 0x0024, 0x3cf0, 0x0024, 0x0000, 0x0280, 0x3490, 0x4024, 0xfe02, + 0x0024, 0x48b2, 0x0024, 0x3810, 0x0024, 0x2802, 0xab80, 0x38f0, 0x4024, + 0x0006, 0x8010, 0x6890, 0x0024, 0x2803, 0x1f00, 0x3800, 0x0024, 0x0000, + 0x0201, 0x2900, 0xb740, 0x3613, 0x11cc, 0x3c10, 0x0024, 0x3490, 0x4024, + 0x6014, 0x13cc, 0x0000, 0x0081, 0x2802, 0xaec5, 0x0006, 0x80d0, 0x0006, + 0x8010, 0x6890, 0x0024, 0x2803, 0x1f00, 0x3800, 0x0024, 0x3010, 0x0024, + 0x6012, 0x0024, 0x0000, 0x0241, 0x2802, 0xce49, 0x0006, 0x8112, 0x0008, + 0x0001, 0x3009, 0x184c, 0x3e10, 0x4024, 0x3000, 0x8024, 0x2901, 0xbac0, + 0x3e00, 0x8024, 0x36f3, 0x004c, 0x3000, 0x3844, 0x0008, 0x0010, 0xb884, + 0x3840, 0x0000, 0x0400, 0x3e00, 0x8024, 0x3201, 0x0024, 0x2903, 0x5680, + 0x6408, 0x4091, 0x0001, 0x0000, 0x000b, 0x8011, 0x0004, 0x0010, 0x36e3, + 0x0024, 0x2915, 0x8300, 0x3009, 0x1bc4, 0x000b, 0x8000, 0x3613, 0x0024, + 0x3e10, 0x0024, 0x3200, 0xc024, 0x2901, 0xbac0, 0x3e00, 0xc024, 0x36f3, + 0x084c, 0x32f0, 0xf844, 0x3e10, 0xc024, 0x3e00, 0x8024, 0x2b01, 0x0091, + 0x0000, 0x0400, 0xf204, 0x0804, 0x2903, 0x5680, 0x6408, 0x0024, 0x000b, + 0x8011, 0x0008, 0x0010, 0x0000, 0x0084, 0x36d3, 0x0024, 0x2915, 0x8300, + 0x0003, 0x8000, 0x0005, 0x0010, 0x0001, 0x0000, 0x2915, 0x8300, 0x000f, + 0x0011, 0x1006, 0x0ac0, 0x32f3, 0x11cc, 0x3200, 0xd08c, 0xff34, 0x0024, + 0x48b6, 0x0024, 0x4020, 0x0024, 0x3c90, 0x0024, 0x2802, 0xca80, 0x34e3, + 0x0024, 0x0006, 0x8112, 0x3613, 0x0024, 0x3e10, 0x0024, 0x3000, 0x4024, + 0x2901, 0xbac0, 0x3e00, 0x4024, 0x36f3, 0x004c, 0x3000, 0x7844, 0xb884, + 0x3841, 0x2b01, 0x0091, 0x0000, 0x0400, 0x3e00, 0x8024, 0x3201, 0x0024, + 0x2903, 0x5680, 0x6408, 0x0024, 0x0003, 0x8000, 0x000b, 0x8011, 0x0008, + 0x0010, 0x36e3, 0x11cc, 0x3423, 0x0024, 0x3494, 0xc024, 0x2903, 0x7ac0, + 0x3301, 0x138c, 0x0001, 0x0000, 0x000f, 0x0011, 0x0004, 0x0010, 0x2903, + 0x8000, 0x3301, 0x0024, 0xf400, 0x4510, 0x000b, 0x8011, 0x3073, 0x0024, + 0x3023, 0x0024, 0x3000, 0x0024, 0x6090, 0x0024, 0x3800, 0x0024, 0x0003, + 0x8000, 0x3004, 0xc024, 0x0008, 0x0010, 0x2903, 0x8000, 0x3301, 0x0024, + 0x0001, 0x0000, 0x000f, 0x0011, 0x0005, 0x0010, 0x2903, 0x8000, 0x3301, + 0x0024, 0xf400, 0x4510, 0x3073, 0x1bc4, 0x6498, 0x008c, 0x3000, 0x0024, + 0x6090, 0x0024, 0x3800, 0x0024, 0x0006, 0x80d0, 0x3000, 0x0024, 0x6402, + 0x0024, 0x0006, 0x8110, 0x2802, 0xbdc8, 0x000b, 0x8000, 0x000b, 0x8010, + 0x0001, 0x0000, 0x2903, 0xe0c0, 0x0004, 0x0011, 0x0005, 0x0011, 0x000b, + 0x8010, 0x0001, 0x0000, 0x291f, 0xc6c0, 0x0002, 0xdf88, 0x30e1, 0x184c, + 0x3000, 0x0024, 0x6012, 0x0024, 0x0008, 0x0001, 0x2802, 0xd015, 0x0000, + 0x0024, 0x6498, 0x0024, 0x3e10, 0x4024, 0x0000, 0x0081, 0x2901, 0xbac0, + 0x3e01, 0x0024, 0x36e3, 0x004c, 0x3000, 0x0024, 0x6012, 0x0024, 0x000b, + 0x8011, 0x2802, 0xdc55, 0x0006, 0x8112, 0x0000, 0x0201, 0x0004, 0x0010, + 0x2915, 0x8300, 0x0001, 0x0000, 0x000b, 0x8011, 0x0005, 0x0010, 0x291f, + 0xc6c0, 0x0001, 0x0000, 0x0006, 0x8110, 0x30e1, 0x0024, 0x3000, 0x0024, + 0x6012, 0x0024, 0x0000, 0x0281, 0x2802, 0xd745, 0x6012, 0x0024, 0x000b, + 0x8001, 0x2802, 0xd7d5, 0x3613, 0x0024, 0x36f3, 0x0024, 0x000b, 0x8001, + 0x6498, 0x184c, 0x0006, 0x8112, 0x0003, 0x8000, 0x3e10, 0x4024, 0x2901, + 0xbac0, 0x3e01, 0x0024, 0x36f3, 0x0024, 0x3009, 0x3844, 0x3e10, 0x0024, + 0x0000, 0x0400, 0x3000, 0x8024, 0x0008, 0x0010, 0x3e00, 0x8024, 0x3201, + 0x0024, 0x2903, 0x5680, 0x6408, 0x4051, 0x36e3, 0x0024, 0x2802, 0xdf80, + 0x3009, 0x1bc4, 0x0000, 0x0400, 0x0000, 0x0011, 0x3613, 0x008c, 0x30d0, + 0x7844, 0x3e10, 0x4024, 0x3000, 0x8024, 0x0008, 0x0010, 0x3e00, 0x8024, + 0x3201, 0x0024, 0x2903, 0x5680, 0x6408, 0x0024, 0x36e3, 0x0024, 0x3009, + 0x1bc4, 0x0006, 0x8a10, 0x0000, 0x01c1, 0x3009, 0x0000, 0xb010, 0x0024, + 0x0000, 0x0024, 0x2802, 0xe385, 0x6192, 0x0024, 0x2900, 0xb740, 0x6102, + 0x184c, 0x4088, 0x0024, 0x0000, 0x0024, 0x2802, 0xe385, 0x0000, 0x0024, + 0x0006, 0x8051, 0x6890, 0x0024, 0x3900, 0x0024, 0x3009, 0x0000, 0x4080, + 0x0024, 0x0000, 0x0024, 0x2903, 0x8e85, 0x0002, 0xe848, 0x0006, 0x9f92, + 0x0000, 0x4003, 0x3009, 0x0811, 0x3100, 0x8024, 0xffa6, 0x0024, 0x48b6, + 0x0024, 0x2903, 0x8e80, 0x4384, 0x0024, 0x2903, 0x8f40, 0x3613, 0x0024, + 0x2900, 0xbf40, 0x0000, 0x0024, 0x2903, 0x8e80, 0x0000, 0x0024, 0x0000, + 0x0401, 0x3473, 0x184c, 0x2900, 0xb740, 0x3c10, 0x0024, 0x3c90, 0x0024, + 0x290b, 0x1400, 0x34f3, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, + 0x1b95, 0x0000, 0x0024, 0x3473, 0x0024, 0x3410, 0x0024, 0x34a0, 0x4024, + 0x6014, 0x1380, 0x0000, 0x0024, 0x2802, 0xf045, 0x4080, 0x0024, 0x0006, + 0x8011, 0x6890, 0x0024, 0xb882, 0x2400, 0x0004, 0x8000, 0x2914, 0xbec0, + 0x0008, 0x0010, 0x0000, 0x0400, 0x3143, 0x108c, 0x6890, 0x27c0, 0x3920, + 0x0024, 0x0004, 0x8000, 0x3900, 0x0024, 0x34e0, 0x0024, 0x4080, 0x0024, + 0x0006, 0x8150, 0x2802, 0xf445, 0x0000, 0x3200, 0x0000, 0x0142, 0x0006, + 0x8210, 0x3613, 0x0024, 0x3e00, 0x7800, 0x3011, 0x8024, 0x30d1, 0xc024, + 0xfef4, 0x4087, 0x48b6, 0x0040, 0xfeee, 0x03c1, 0x2914, 0xa580, 0x42b6, + 0x0024, 0x2802, 0xf840, 0x0007, 0x89d0, 0x0000, 0x0142, 0x3613, 0x0024, + 0x3e00, 0x7800, 0x3031, 0x8024, 0x3010, 0x0024, 0x30d0, 0x4024, 0xfe9c, + 0x4181, 0x48be, 0x0024, 0xfe82, 0x0040, 0x46be, 0x03c1, 0xfef4, 0x4087, + 0x48b6, 0x0024, 0xfeee, 0x0024, 0x2914, 0xa580, 0x42b6, 0x0024, 0x0007, + 0x89d0, 0x0006, 0x8191, 0x4c8a, 0x9800, 0xfed0, 0x4005, 0x48b2, 0x0024, + 0xfeca, 0x0024, 0x40b2, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x3111, + 0x8024, 0x468a, 0x0707, 0x2908, 0xbe80, 0x3101, 0x0024, 0x3123, 0x11cc, + 0x3100, 0x108c, 0x3009, 0x3000, 0x0004, 0x8000, 0x3009, 0x1241, 0x6014, + 0x138c, 0x000b, 0x8011, 0x2802, 0xfe81, 0x0000, 0x0024, 0x3473, 0x0024, + 0x3423, 0x0024, 0x3009, 0x3240, 0x34e3, 0x0024, 0x2803, 0x19c0, 0x0008, + 0x0012, 0x0000, 0x0081, 0x2803, 0x0009, 0x0006, 0x80d0, 0xf400, 0x4004, + 0x3000, 0x0024, 0x6012, 0x0024, 0x0000, 0x0005, 0x2803, 0x0589, 0x0000, + 0x0024, 0x6540, 0x0024, 0x0000, 0x0024, 0x2803, 0x15d8, 0x4490, 0x0024, + 0x2403, 0x04c0, 0x0000, 0x0024, 0x0006, 0x8301, 0x4554, 0x0800, 0x4122, + 0x0024, 0x659a, 0x4055, 0x0006, 0x8341, 0x3d00, 0x0840, 0x4122, 0x0024, + 0xf400, 0x4055, 0x3d00, 0x0024, 0x2803, 0x15c0, 0x0000, 0x0024, 0x4090, + 0x0024, 0xf400, 0x4480, 0x2803, 0x0ad5, 0x000b, 0x8001, 0x6540, 0x0024, + 0x0000, 0x0024, 0x2803, 0x15d8, 0x4490, 0x0024, 0x2403, 0x0a00, 0x0000, + 0x0024, 0x0006, 0x8301, 0x4554, 0x0800, 0x4122, 0x0024, 0x659a, 0x4055, + 0x0006, 0x8341, 0x4122, 0x3400, 0xf400, 0x4055, 0x3210, 0x0024, 0x3d00, + 0x0024, 0x2803, 0x15c0, 0x0000, 0x0024, 0x6014, 0x0024, 0x0001, 0x0000, + 0x2803, 0x1215, 0x0003, 0x8001, 0x0008, 0x0012, 0x0008, 0x0010, 0x0006, + 0x8153, 0x3613, 0x0024, 0x3009, 0x3811, 0x2903, 0xe0c0, 0x0004, 0x0011, + 0x0008, 0x0010, 0x0001, 0x0000, 0x291f, 0xc6c0, 0x0005, 0x0011, 0x000f, + 0x0011, 0x0008, 0x0010, 0x33d0, 0x184c, 0x6010, 0xb844, 0x3e10, 0x0024, + 0x0000, 0x0400, 0x3320, 0x4024, 0x3e00, 0x4024, 0x3301, 0x0024, 0x2903, + 0x5680, 0x6408, 0x0024, 0x36e3, 0x0024, 0x3009, 0x1bc4, 0x3009, 0x1bd1, + 0x6540, 0x0024, 0x0000, 0x0024, 0x2803, 0x15d8, 0x4490, 0x0024, 0x2403, + 0x1580, 0x0000, 0x0024, 0x0006, 0x8301, 0x4554, 0x0840, 0x4122, 0x0024, + 0x659a, 0x4055, 0x0006, 0x8341, 0x4122, 0x3400, 0xf400, 0x4055, 0x3110, + 0x0024, 0x3d00, 0x0024, 0xf400, 0x4510, 0x0030, 0x0013, 0x3073, 0x184c, + 0x3e11, 0x008c, 0x3009, 0x0001, 0x6140, 0x0024, 0x0000, 0x0201, 0x3009, + 0x2000, 0x0006, 0x8300, 0x290c, 0x7300, 0x3e10, 0x0024, 0x3300, 0x1b8c, + 0xb010, 0x0024, 0x0000, 0x0024, 0x2803, 0x1b95, 0x0000, 0x0024, 0x3473, + 0x0024, 0x3423, 0x0024, 0x3009, 0x1240, 0x4080, 0x138c, 0x0000, 0x0804, + 0x2802, 0xff15, 0x6402, 0x0024, 0x0006, 0xd312, 0x0006, 0xd310, 0x0006, + 0x8191, 0x3010, 0x984c, 0x30f0, 0xc024, 0x0000, 0x0021, 0xf2d6, 0x07c6, + 0x290a, 0xf5c0, 0x4682, 0x0400, 0x6894, 0x0840, 0xb886, 0x0bc1, 0xbcd6, + 0x0024, 0x3a10, 0x8024, 0x3af0, 0xc024, 0x36f3, 0x4024, 0x36f3, 0xd80e, + 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, + 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, + 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, + 0x0020, 0x0001, 0x3e14, 0x3811, 0x0030, 0x0050, 0x0030, 0x0251, 0x3e04, + 0xb813, 0x3000, 0x0024, 0xc012, 0x0024, 0x0019, 0x9300, 0x3800, 0x4024, + 0x2903, 0x8c40, 0x3900, 0x0024, 0x2903, 0xa040, 0x0000, 0x0300, 0xb882, + 0x0024, 0x2914, 0xbec0, 0x0006, 0x8010, 0x0000, 0x1540, 0x0007, 0x8190, + 0x2901, 0x8200, 0x3800, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, + 0x2f55, 0x0000, 0x0024, 0x0006, 0x8012, 0x3200, 0x0024, 0x4080, 0x0024, + 0x0030, 0x0010, 0x2803, 0x2f55, 0x0000, 0x0201, 0x3000, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0024, 0x2803, 0x2f55, 0x0000, 0x0024, 0x2901, 0x8200, + 0x0000, 0x0024, 0x4080, 0x0024, 0x0006, 0x8010, 0x2803, 0x2f55, 0x3000, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0201, 0x2803, 0x2b85, 0x0030, 0x0010, + 0x0030, 0x0050, 0xf292, 0x0000, 0xb012, 0x0024, 0x3800, 0x4024, 0x0030, + 0x0010, 0x0000, 0x0201, 0x3000, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, + 0x2900, 0xbed5, 0x0003, 0x3908, 0x0006, 0x8011, 0x3100, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0024, 0x2803, 0x3745, 0x0000, 0x0024, 0x0007, 0x8a52, + 0x3200, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, 0x3749, 0x0000, + 0x0024, 0xf292, 0x0800, 0x6012, 0x0024, 0x0000, 0x0000, 0x2803, 0x3705, + 0x0000, 0x0024, 0x3200, 0x0024, 0x4090, 0x0024, 0xb880, 0x2800, 0x3900, + 0x0024, 0x3100, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2902, 0x3585, + 0x0003, 0x3048, 0x2900, 0xbec0, 0x0000, 0x0024, 0x0000, 0x0010, 0x0006, + 0x9f51, 0x0006, 0x9f92, 0x0030, 0x0493, 0x0000, 0x0201, 0x6890, 0xa410, + 0x3b00, 0x2810, 0x0006, 0x8a10, 0x3009, 0x0000, 0x6012, 0x0024, 0x0006, + 0x9fd0, 0x2803, 0x3c88, 0xb880, 0x0024, 0x6890, 0x0024, 0x3009, 0x2000, + 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, + 0x3e10, 0xb810, 0x3e11, 0x3805, 0x3e02, 0x0024, 0x0030, 0x0010, 0xce9a, + 0x0002, 0x0000, 0x0200, 0x2903, 0x47c0, 0xb024, 0x0024, 0xc020, 0x0024, + 0x0000, 0x0200, 0x2803, 0x4085, 0x6e9a, 0x0002, 0x4182, 0x0024, 0x0000, + 0x0400, 0x2803, 0x4645, 0xae1a, 0x0024, 0x6104, 0x984c, 0x0000, 0x0024, + 0x2900, 0xb749, 0x0003, 0x4608, 0x6103, 0xe4e5, 0x2900, 0xb740, 0x408a, + 0x188c, 0x2900, 0xb740, 0x408a, 0x4141, 0x4583, 0x6465, 0x2803, 0x4640, + 0xceca, 0x1bcc, 0xc408, 0x0024, 0xf2e2, 0x1bc8, 0x36f1, 0x1805, 0x2000, + 0x0011, 0x36f0, 0x9810, 0x2000, 0x0000, 0xdc92, 0x0024, 0x0006, 0x8a17, + 0x3613, 0x1c00, 0x6093, 0xe1e3, 0x0000, 0x03c3, 0x0006, 0x9f95, 0xb132, + 0x9415, 0x3500, 0xfc01, 0x2803, 0x55d5, 0xa306, 0x0024, 0x0006, 0xd397, + 0x003f, 0xc001, 0x3500, 0x184c, 0xb011, 0xe4e5, 0xb182, 0x1c04, 0xd400, + 0x184c, 0x0000, 0x0205, 0xac52, 0x3802, 0x0006, 0xd3c2, 0x4212, 0x0024, + 0xf400, 0x4057, 0xb182, 0x1c04, 0xd400, 0x0024, 0xac52, 0x1404, 0xd142, + 0x0024, 0x0000, 0x3fc4, 0xb142, 0x0024, 0x4122, 0x1bc2, 0xf400, 0x4057, + 0x3700, 0x4024, 0xd101, 0x6465, 0x0006, 0xd397, 0x3f00, 0x3814, 0x0025, + 0xffd4, 0x0006, 0xd317, 0x3710, 0x160c, 0x0006, 0x9f94, 0x37f0, 0x73d5, + 0x6c92, 0x3808, 0x3f10, 0x0024, 0x3ff0, 0x4024, 0x3009, 0x1040, 0x3009, + 0x13c1, 0x6010, 0x0024, 0x0000, 0x0024, 0x2903, 0xa905, 0x0003, 0x51c8, + 0x2803, 0x5414, 0x0006, 0x0001, 0x4010, 0x0024, 0x0005, 0xf601, 0x6010, + 0x0024, 0x0000, 0x0040, 0x2803, 0x5594, 0x0030, 0x0497, 0x3f00, 0x0024, + 0x36f2, 0x1814, 0x4330, 0x9803, 0x2000, 0x0000, 0x8880, 0x1bc1, 0x3613, + 0x0024, 0x3e22, 0xb806, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x7807, 0x6848, 0x930c, 0x3411, + 0x780d, 0x459a, 0x10c0, 0x0000, 0x0201, 0x6012, 0x384e, 0x0000, 0x0241, + 0x2803, 0x5d15, 0x6012, 0x380f, 0x2403, 0x5c45, 0x0000, 0x0024, 0x3000, + 0x0001, 0x3101, 0x8407, 0x6cfe, 0x0024, 0xac42, 0x0024, 0xaf4e, 0x2040, + 0x3911, 0x8024, 0x2803, 0x68c0, 0x0000, 0x0024, 0x0000, 0x0281, 0x2803, + 0x6055, 0x6012, 0x4455, 0x2403, 0x5f85, 0x0000, 0x0024, 0x3000, 0x0001, + 0x3101, 0x8407, 0x4cf2, 0x0024, 0xac42, 0x0024, 0xaf4e, 0x2040, 0x3911, + 0x8024, 0x2803, 0x68c0, 0x0000, 0x0024, 0x0000, 0x0024, 0x2803, 0x6495, + 0x4080, 0x0024, 0x3110, 0x0401, 0xf20f, 0x0203, 0x2403, 0x63c5, 0x8dd6, + 0x0024, 0x4dce, 0x0024, 0xf1fe, 0x0024, 0xaf4e, 0x0024, 0x6dc6, 0x2046, + 0xf1df, 0x0203, 0xaf4f, 0x1011, 0xf20e, 0x07cc, 0x8dd6, 0x2486, 0x2803, + 0x68c0, 0x0000, 0x0024, 0x0000, 0x0024, 0x2803, 0x6715, 0x0000, 0x0024, + 0x0fff, 0xffd1, 0x2403, 0x6645, 0x3010, 0x0001, 0xac4f, 0x0801, 0x3821, + 0x8024, 0x2803, 0x68c0, 0x0000, 0x0024, 0x0fff, 0xffd1, 0x2403, 0x6885, + 0x3010, 0x0001, 0x3501, 0x9407, 0xac47, 0x0801, 0xaf4e, 0x2082, 0x3d11, + 0x8024, 0x36f3, 0xc024, 0x36f3, 0x980d, 0x36f1, 0x5807, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, + 0x9806, 0x0006, 0x9f97, 0x3e00, 0x5c15, 0x0006, 0xd397, 0x003f, 0xc001, + 0x3500, 0x3840, 0xb011, 0xe4e5, 0xb182, 0x1c04, 0xd400, 0x184c, 0x0000, + 0x0205, 0xac52, 0x3802, 0x0006, 0xd3c2, 0x4212, 0x0024, 0xb182, 0x4057, + 0x3701, 0x0024, 0xd400, 0x0024, 0xac52, 0x1404, 0xd142, 0x0024, 0x0000, + 0x3fc4, 0xb142, 0x0024, 0x4122, 0x1bc2, 0xf400, 0x4057, 0x3700, 0x4024, + 0xd101, 0x6465, 0x0006, 0xd397, 0x3f00, 0x3814, 0x0025, 0xffd4, 0x0006, + 0xd317, 0x3710, 0x160c, 0x0006, 0x9f94, 0x37f0, 0x73d5, 0x6c92, 0x0024, + 0x3f10, 0x1040, 0x3ff0, 0x53c1, 0x6010, 0x0024, 0x0000, 0x0024, 0x2803, + 0x7494, 0x0006, 0x0001, 0x4010, 0x0024, 0x0005, 0xf601, 0x6010, 0x9bd4, + 0x0000, 0x0040, 0x2803, 0x7614, 0x0030, 0x0497, 0x3f00, 0x0024, 0x2000, + 0x0000, 0x36f0, 0x5800, 0x0000, 0x0400, 0x6102, 0x0024, 0x3e11, 0x3805, + 0x2803, 0x7989, 0x3e02, 0x0024, 0x2900, 0xb740, 0x408a, 0x188c, 0x2900, + 0xb740, 0x408a, 0x4141, 0x4582, 0x1bc8, 0x2000, 0x0000, 0x36f1, 0x1805, + 0x2900, 0xb740, 0x4102, 0x184c, 0xb182, 0x1bc8, 0x2000, 0x0000, 0x36f1, + 0x1805, 0x3613, 0x0024, 0x3e12, 0xb815, 0x3e11, 0xb807, 0x3e13, 0xf80e, + 0x3e03, 0x4024, 0x680c, 0x0024, 0x0000, 0x0024, 0x2803, 0x7ed8, 0x409c, + 0x0024, 0x2403, 0x7e86, 0x0000, 0x000a, 0x3111, 0xc024, 0xfe4e, 0x0007, + 0x47be, 0x0024, 0xf6fe, 0x0024, 0x3811, 0xc024, 0x36f3, 0x4024, 0x36f3, + 0xd80e, 0x36f1, 0x9807, 0x2000, 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, + 0x3e12, 0xb815, 0x3e11, 0xb807, 0x3e13, 0xf80e, 0x3e03, 0x4024, 0x680c, + 0x0024, 0x0000, 0x0024, 0x2803, 0x8418, 0x409c, 0x0024, 0x2403, 0x83c6, + 0x0000, 0x000a, 0x3111, 0xc024, 0xfe4e, 0x8007, 0x47be, 0x0024, 0xf6fe, + 0x0024, 0x3009, 0x2047, 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x36f1, 0x9807, + 0x2000, 0x0000, 0x36f2, 0x9815, 0x2a03, 0x858e, 0x3e12, 0xb817, 0x3e10, + 0x3802, 0x0000, 0x800a, 0x0006, 0x9f97, 0x3009, 0x1fc2, 0x3e04, 0x5c00, + 0x6020, 0xb810, 0x0030, 0x0451, 0x2803, 0x8854, 0x0006, 0x0002, 0x4020, + 0x0024, 0x0005, 0xfb02, 0x6024, 0x0024, 0x0025, 0xffd0, 0x2803, 0x8a91, + 0x3100, 0x1c11, 0xb284, 0x0024, 0x0030, 0x0490, 0x3800, 0x8024, 0x0025, + 0xffd0, 0x3980, 0x1810, 0x36f4, 0x7c11, 0x36f0, 0x1802, 0x0030, 0x0717, + 0x3602, 0x8024, 0x2100, 0x0000, 0x3f05, 0xdbd7, 0x0003, 0x8557, 0x3613, + 0x0024, 0x3e00, 0x3801, 0xf400, 0x55c0, 0x0000, 0x0897, 0xf400, 0x57c0, + 0x0000, 0x0024, 0x2000, 0x0000, 0x36f0, 0x1801, 0x0006, 0xd397, 0x2000, + 0x0000, 0x3700, 0x0024, 0xb183, 0xe1e3, 0x0000, 0x0203, 0xac32, 0x40d5, + 0xd122, 0x0024, 0x0000, 0x3fc3, 0xb132, 0x0024, 0x0006, 0xd3c3, 0x4316, + 0x0024, 0xf400, 0x40d5, 0x3500, 0x5803, 0x2000, 0x0000, 0xd010, 0x1bc1, + 0x3613, 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0xb884, 0xb805, 0xb888, 0x3844, + 0x3e11, 0xb80d, 0x3e03, 0xf80e, 0x0000, 0x03ce, 0xf400, 0x4083, 0x2403, + 0x9ace, 0xf400, 0x4105, 0x0000, 0x0206, 0xa562, 0x0024, 0x455a, 0x0024, + 0x0020, 0x0006, 0xd312, 0x0024, 0xb16c, 0x0024, 0x0020, 0x0006, 0x2803, + 0x9945, 0xd342, 0x0024, 0x0000, 0x01c6, 0xd342, 0x0024, 0xd56a, 0x0024, + 0x0020, 0x0006, 0x4448, 0x0024, 0xb16c, 0x0024, 0x0020, 0x0146, 0x2803, + 0x9ac5, 0x0000, 0x0024, 0xd468, 0x0024, 0x4336, 0x0024, 0x0000, 0x4000, + 0x0006, 0xd3c1, 0x0006, 0x9306, 0x4122, 0x0024, 0x462c, 0x4055, 0x4092, + 0x3404, 0xb512, 0x4195, 0x6294, 0x3401, 0x6200, 0x0024, 0x0000, 0x03ce, + 0x2803, 0x9551, 0xb888, 0x0024, 0x36f3, 0xd80e, 0x36f1, 0x980d, 0x36f1, + 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36e3, 0x0024, + 0x2000, 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, + 0xb880, 0xb810, 0x0006, 0x9fd0, 0x3e10, 0x8001, 0x4182, 0x3811, 0x0006, + 0xd311, 0x2803, 0xa405, 0x0006, 0x8a10, 0x0000, 0x0200, 0xbc82, 0xa000, + 0x3910, 0x0024, 0x2903, 0x9240, 0x39f0, 0x4024, 0x0006, 0x9f90, 0x0006, + 0x9f51, 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, 0x0024, 0x0000, 0x0024, + 0x2903, 0xa905, 0x0003, 0xa508, 0x36f4, 0x4024, 0x36f0, 0x9810, 0x36f0, + 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, + 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x290a, 0xd900, 0x3605, 0x0024, 0x2910, 0x0180, 0x3613, 0x0024, + 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, + 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, + 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x0006, 0x0002, 0x3e11, + 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x0006, 0x9f90, 0x3e04, 0xb813, + 0x3009, 0x0012, 0x3213, 0x0024, 0xf400, 0x4480, 0x6026, 0x0024, 0x0000, + 0x0024, 0x2803, 0xb195, 0x0000, 0x0024, 0x0000, 0x0012, 0xf400, 0x4480, + 0x0006, 0x9f50, 0x3009, 0x0002, 0x6026, 0x0024, 0x0000, 0x0024, 0x2903, + 0xa905, 0x0003, 0xb188, 0x0006, 0x9f93, 0x3201, 0x0c11, 0xb58a, 0x0406, + 0x0006, 0x8a11, 0x468e, 0x8400, 0xb68c, 0x9813, 0xcfee, 0x1bd2, 0x0000, + 0x0804, 0xaf0e, 0x9811, 0x4f86, 0x1bd0, 0x0000, 0x0021, 0x6418, 0x9807, + 0x6848, 0x1bc6, 0xad46, 0x9805, 0xf400, 0x4080, 0x36f1, 0x0024, 0x36f0, + 0x9803, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, + 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, + 0x3e11, 0x3805, 0x2803, 0xbfc0, 0x3e04, 0x3811, 0x0000, 0x0401, 0x2900, + 0xb740, 0x3613, 0x0024, 0x0000, 0x0080, 0xb882, 0x130c, 0xf400, 0x4510, + 0x3010, 0x910c, 0x30f0, 0xc024, 0x6dc2, 0x0024, 0x3810, 0x0024, 0x38f0, + 0x4024, 0x0000, 0x0201, 0x3100, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, + 0x2803, 0xc315, 0x0000, 0x0024, 0x6894, 0x130c, 0xb886, 0x1040, 0x3430, + 0x4024, 0x6dca, 0x0024, 0x0030, 0x0011, 0x2803, 0xbb91, 0x0000, 0x0024, + 0xbcd2, 0x0024, 0x0000, 0x0201, 0x2803, 0xc305, 0x0000, 0x0024, 0x2900, + 0xb740, 0x3613, 0x0024, 0x36f4, 0x1811, 0x36f1, 0x1805, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb815, 0x0000, 0x800a, + 0x3e14, 0x7813, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e13, + 0xf80e, 0x6812, 0x0024, 0x3e03, 0x7810, 0x0fff, 0xffd3, 0x0000, 0x0091, + 0xbd86, 0x9850, 0x3e10, 0x3804, 0x3e00, 0x7812, 0xbe8a, 0x8bcc, 0x409e, + 0x8086, 0x2403, 0xca47, 0xfe49, 0x2821, 0x526a, 0x8801, 0x5c87, 0x280e, + 0x4eba, 0x9812, 0x4286, 0x40e1, 0xb284, 0x1bc1, 0x4de6, 0x0024, 0xad17, + 0x2627, 0x4fde, 0x9804, 0x4498, 0x1bc0, 0x0000, 0x0024, 0x2803, 0xc855, + 0x3a11, 0xa807, 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x36f1, 0x9807, 0x36f1, + 0x1805, 0x36f0, 0x9803, 0x36f4, 0x5813, 0x2000, 0x0000, 0x36f2, 0x9815, + 0x3613, 0x0024, 0x3e12, 0xb815, 0x0000, 0x800a, 0x3e10, 0xb803, 0x3e11, + 0x3805, 0x3e11, 0xb807, 0x3e13, 0xf80e, 0x6812, 0x0024, 0x3e03, 0x7810, + 0x3009, 0x1850, 0x3e10, 0x3804, 0x3e10, 0x7812, 0x32f3, 0x0024, 0xbd86, + 0x0024, 0x4091, 0xe2e3, 0x3009, 0x0046, 0x2403, 0xd5c0, 0x3009, 0x0047, + 0x32f0, 0x0801, 0xfe1f, 0x6465, 0x5e8a, 0x0024, 0x44ba, 0x0024, 0xfee2, + 0x0024, 0x5d8a, 0x1800, 0x4482, 0x4160, 0x48ba, 0x8046, 0x4dc6, 0x1822, + 0x4de6, 0x8047, 0x36f3, 0x0024, 0x36f0, 0x5812, 0xad17, 0x2627, 0x4fde, + 0x9804, 0x4498, 0x1bc0, 0x0000, 0x0024, 0x2803, 0xd155, 0x3a11, 0xa807, + 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, + 0x9803, 0x2000, 0x0000, 0x36f2, 0x9815, 0xb386, 0x40d7, 0x4284, 0x184c, + 0x0000, 0x05c0, 0x2803, 0xdb55, 0xf5d8, 0x3804, 0x0000, 0x0984, 0x6400, + 0xb84a, 0x3e13, 0xf80d, 0xa204, 0x380e, 0x0000, 0x800a, 0x0000, 0x00ce, + 0x2403, 0xde8e, 0xffa4, 0x0024, 0x48b6, 0x0024, 0x0000, 0x0024, 0x2803, + 0xde84, 0x4000, 0x40c2, 0x4224, 0x0024, 0x6090, 0x0024, 0xffa4, 0x0024, + 0x0fff, 0xfe83, 0xfe86, 0x1bce, 0x36f3, 0xd80d, 0x48b6, 0x0024, 0x0fff, + 0xff03, 0xa230, 0x45c3, 0x2000, 0x0000, 0x36f1, 0x180a, 0x4080, 0x184c, + 0x3e13, 0x780f, 0x2803, 0xe2c5, 0x4090, 0xb80e, 0x2403, 0xe240, 0x3e04, + 0x0440, 0x3810, 0x0440, 0x3604, 0x0024, 0x3009, 0x1bce, 0x3603, 0x5bcf, + 0x2000, 0x0000, 0x0000, 0x0024, 0x0007, 0x0001, /*copy 1*/ + 0x802e, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x6ac0, 0x0007, 0x0001, /*copy 1*/ + 0x8030, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x1b40, 0x0007, 0x0001, /*copy 1*/ + 0x8028, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x144e, 0x0007, 0x0001, /*copy 1*/ + 0x8032, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x7140, 0x0007, 0x0001, /*copy 1*/ + 0x3580, 0x0006, 0x8038, 0x0000, /*Rle(56)*/ + 0x0007, 0x0001, /*copy 1*/ + 0xfab3, 0x0006, 0x01a4, /*copy 420*/ + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0xffff, 0xfffe, 0xfffb, 0xfff9, + 0xfff5, 0xfff2, 0xffed, 0xffe8, 0xffe3, 0xffde, 0xffd8, 0xffd3, 0xffce, + 0xffca, 0xffc7, 0xffc4, 0xffc4, 0xffc5, 0xffc7, 0xffcc, 0xffd3, 0xffdc, + 0xffe6, 0xfff3, 0x0001, 0x0010, 0x001f, 0x002f, 0x003f, 0x004e, 0x005b, + 0x0066, 0x006f, 0x0074, 0x0075, 0x0072, 0x006b, 0x005f, 0x004f, 0x003c, + 0x0024, 0x0009, 0xffed, 0xffcf, 0xffb0, 0xff93, 0xff77, 0xff5f, 0xff4c, + 0xff3d, 0xff35, 0xff34, 0xff3b, 0xff4a, 0xff60, 0xff7e, 0xffa2, 0xffcd, + 0xfffc, 0x002e, 0x0061, 0x0094, 0x00c4, 0x00f0, 0x0114, 0x0131, 0x0144, + 0x014b, 0x0146, 0x0134, 0x0116, 0x00eb, 0x00b5, 0x0075, 0x002c, 0xffde, + 0xff8e, 0xff3d, 0xfeef, 0xfea8, 0xfe6a, 0xfe39, 0xfe16, 0xfe05, 0xfe06, + 0xfe1b, 0xfe43, 0xfe7f, 0xfecd, 0xff2a, 0xff95, 0x0009, 0x0082, 0x00fd, + 0x0173, 0x01e1, 0x0242, 0x0292, 0x02cc, 0x02ec, 0x02f2, 0x02da, 0x02a5, + 0x0253, 0x01e7, 0x0162, 0x00c9, 0x0021, 0xff70, 0xfebc, 0xfe0c, 0xfd68, + 0xfcd5, 0xfc5b, 0xfc00, 0xfbc9, 0xfbb8, 0xfbd2, 0xfc16, 0xfc85, 0xfd1b, + 0xfdd6, 0xfeae, 0xff9e, 0x009c, 0x01a0, 0x02a1, 0x0392, 0x046c, 0x0523, + 0x05b0, 0x060a, 0x062c, 0x0613, 0x05bb, 0x0526, 0x0456, 0x0351, 0x021f, + 0x00c9, 0xff5a, 0xfde1, 0xfc6a, 0xfb05, 0xf9c0, 0xf8aa, 0xf7d0, 0xf73d, + 0xf6fa, 0xf70f, 0xf77e, 0xf848, 0xf96b, 0xfadf, 0xfc9a, 0xfe8f, 0x00ad, + 0x02e3, 0x051a, 0x073f, 0x0939, 0x0af4, 0x0c5a, 0x0d59, 0x0de1, 0x0de5, + 0x0d5c, 0x0c44, 0x0a9e, 0x0870, 0x05c7, 0x02b4, 0xff4e, 0xfbaf, 0xf7f8, + 0xf449, 0xf0c7, 0xed98, 0xeae0, 0xe8c4, 0xe765, 0xe6e3, 0xe756, 0xe8d2, + 0xeb67, 0xef19, 0xf3e9, 0xf9cd, 0x00b5, 0x088a, 0x112b, 0x1a72, 0x2435, + 0x2e42, 0x3866, 0x426b, 0x4c1b, 0x553e, 0x5da2, 0x6516, 0x6b6f, 0x7087, + 0x7441, 0x7686, 0x774a, 0x7686, 0x7441, 0x7087, 0x6b6f, 0x6516, 0x5da2, + 0x553e, 0x4c1b, 0x426b, 0x3866, 0x2e42, 0x2435, 0x1a72, 0x112b, 0x088a, + 0x00b5, 0xf9cd, 0xf3e9, 0xef19, 0xeb67, 0xe8d2, 0xe756, 0xe6e3, 0xe765, + 0xe8c4, 0xeae0, 0xed98, 0xf0c7, 0xf449, 0xf7f8, 0xfbaf, 0xff4e, 0x02b4, + 0x05c7, 0x0870, 0x0a9e, 0x0c44, 0x0d5c, 0x0de5, 0x0de1, 0x0d59, 0x0c5a, + 0x0af4, 0x0939, 0x073f, 0x051a, 0x02e3, 0x00ad, 0xfe8f, 0xfc9a, 0xfadf, + 0xf96b, 0xf848, 0xf77e, 0xf70f, 0xf6fa, 0xf73d, 0xf7d0, 0xf8aa, 0xf9c0, + 0xfb05, 0xfc6a, 0xfde1, 0xff5a, 0x00c9, 0x021f, 0x0351, 0x0456, 0x0526, + 0x05bb, 0x0613, 0x062c, 0x060a, 0x05b0, 0x0523, 0x046c, 0x0392, 0x02a1, + 0x01a0, 0x009c, 0xff9e, 0xfeae, 0xfdd6, 0xfd1b, 0xfc85, 0xfc16, 0xfbd2, + 0xfbb8, 0xfbc9, 0xfc00, 0xfc5b, 0xfcd5, 0xfd68, 0xfe0c, 0xfebc, 0xff70, + 0x0021, 0x00c9, 0x0162, 0x01e7, 0x0253, 0x02a5, 0x02da, 0x02f2, 0x02ec, + 0x02cc, 0x0292, 0x0242, 0x01e1, 0x0173, 0x00fd, 0x0082, 0x0009, 0xff95, + 0xff2a, 0xfecd, 0xfe7f, 0xfe43, 0xfe1b, 0xfe06, 0xfe05, 0xfe16, 0xfe39, + 0xfe6a, 0xfea8, 0xfeef, 0xff3d, 0xff8e, 0xffde, 0x002c, 0x0075, 0x00b5, + 0x00eb, 0x0116, 0x0134, 0x0146, 0x014b, 0x0144, 0x0131, 0x0114, 0x00f0, + 0x00c4, 0x0094, 0x0061, 0x002e, 0xfffc, 0xffcd, 0xffa2, 0xff7e, 0xff60, + 0xff4a, 0xff3b, 0xff34, 0xff35, 0xff3d, 0xff4c, 0xff5f, 0xff77, 0xff93, + 0xffb0, 0xffcf, 0xffed, 0x0009, 0x0024, 0x003c, 0x004f, 0x005f, 0x006b, + 0x0072, 0x0075, 0x0074, 0x006f, 0x0066, 0x005b, 0x004e, 0x003f, 0x002f, + 0x001f, 0x0010, 0x0001, 0xfff3, 0xffe6, 0xffdc, 0xffd3, 0xffcc, 0xffc7, + 0xffc5, 0xffc4, 0xffc4, 0xffc7, 0xffca, 0xffce, 0xffd3, 0xffd8, 0xffde, + 0xffe3, 0xffe8, 0xffed, 0xfff2, 0xfff5, 0xfff9, 0xfffb, 0xfffe, 0xffff, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0007, 0x0001, /*copy 1*/ + 0x180b, 0x0006, 0x000d, /*copy 13*/ + 0x000f, 0x0010, 0x001c, 0xfab3, 0x3580, 0x8037, 0xa037, 0x0001, 0x0000, + 0x3580, 0x01a4, 0x0728, 0x0746, 0x0006, 0x8006, 0x078e, /*Rle(6)*/ + 0x0006, 0x0027, /*copy 39*/ + 0x0763, 0x0763, 0x0763, 0x0763, 0x0763, 0x0992, 0x0976, 0x097a, 0x097e, + 0x0982, 0x0986, 0x098a, 0x098e, 0x09c1, 0x09c5, 0x09c8, 0x09c8, 0x09c8, + 0x09c8, 0x09d0, 0x09e3, 0x0aae, 0x0a1a, 0x0a1f, 0x0a25, 0x0a2b, 0x0a30, + 0x0a35, 0x0a3a, 0x0a3f, 0x0a44, 0x0a49, 0x0a4e, 0x0a53, 0x0a6c, 0x0a8b, + 0x0aaa, 0x5a82, 0x5a82, 0x0006, 0x8006, 0x0000, /*Rle(6)*/ + 0x0006, 0x0018, /*copy 24*/ + 0x6fb8, 0xc180, 0xc180, 0x6fb8, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a82, + 0x5a82, 0x6fb8, 0xc180, 0xc180, 0x6fb8, 0x0000, 0x0000, 0x5a82, 0x5a82, + 0x5a82, 0x5a82, 0x6fb8, 0xc180, 0xc180, 0x6fb8, 0x0007, 0x0001, /*copy 1*/ + 0x8025, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x5c4e, 0x0007, 0x0001, /*copy 1*/ + 0x5800, 0x0006, 0x0001, /*copy 1*/ + 0x0001, 0x0006, 0x8007, 0x0000, /*Rle(7)*/ + 0x0006, 0x0018, /*copy 24*/ + 0x0002, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, + 0x0000, 0xfffd, 0xffff, 0x0001, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, + 0xfffa, 0xffff, 0x0004, 0x0000, 0xffff, 0xffff, 0x000a, 0x0001, /*copy 1*/ + 0x0050, +#define PLUGIN_SIZE 8414 +#ifndef SKIP_PLUGIN_VARNAME +}; +#endif diff --git a/targets/esp32/components/VS1053/include/patches_flac_latm.h b/targets/esp32/components/VS1053/include/patches_flac_latm.h new file mode 100644 index 00000000..e44ba0ba --- /dev/null +++ b/targets/esp32/components/VS1053/include/patches_flac_latm.h @@ -0,0 +1,980 @@ + +#ifndef SKIP_PLUGIN_VARNAME +const unsigned short PLUGIN[] = { + /* Compressed plugin */ +#endif + 0x0007, 0x0001, /*copy 1*/ + 0x8050, 0x0006, 0x0558, /*copy 1368*/ + 0x2a00, 0xc000, 0x3e12, 0x3800, 0x3e00, 0xb804, 0x0030, 0x0015, 0x0007, + 0x8257, 0x3700, 0x984c, 0xf224, 0x1444, 0xf224, 0x0024, 0x0008, 0x0002, + 0x2910, 0x0181, 0x0000, 0x14c8, 0xb428, 0x1402, 0x0000, 0x8004, 0x2910, + 0x0195, 0x0000, 0x14c8, 0xb428, 0x0024, 0x0006, 0x0095, 0x2800, 0x2245, + 0x3e13, 0x780e, 0x3e11, 0x7803, 0x3e13, 0xf806, 0x3e11, 0xf801, 0x3510, + 0xb808, 0x003f, 0xe004, 0xfec4, 0x3800, 0x48be, 0x17c3, 0xfec6, 0x41c2, + 0x48be, 0x4497, 0x4090, 0x1c46, 0xf06c, 0x0024, 0x2400, 0x1e80, 0x6090, + 0x41c3, 0x6628, 0x1c47, 0x0000, 0x0024, 0x2800, 0x1d49, 0xf07e, 0x0024, + 0xf400, 0x4182, 0x673a, 0x1c46, 0x0000, 0x0024, 0x2800, 0x1e89, 0xf06c, + 0x0024, 0xf400, 0x41c3, 0x0000, 0x0024, 0x4224, 0x3442, 0x2903, 0xf500, + 0x4336, 0x37c3, 0x0000, 0x1805, 0x2903, 0xf500, 0x4508, 0x40c2, 0x450a, + 0x9808, 0x0000, 0x0207, 0xa478, 0x1bc0, 0xc45a, 0x1807, 0x0030, 0x03d5, + 0x3d01, 0x5bc1, 0x36f3, 0xd806, 0x3601, 0x5803, 0x36f3, 0x0024, 0x36f3, + 0x580e, 0x0007, 0x8257, 0x0000, 0x6004, 0x3730, 0x8024, 0xb244, 0x1c04, + 0xd428, 0x3c02, 0x0006, 0xc717, 0x2800, 0x2605, 0x4284, 0x0024, 0x3613, + 0x3c02, 0x0006, 0xc357, 0x2901, 0x6280, 0x3e11, 0x5c05, 0x4284, 0x1bc5, + 0x0000, 0x0024, 0x2800, 0x2945, 0x0000, 0x0024, 0x0030, 0x0117, 0x3f00, + 0x0024, 0x3613, 0x0024, 0x3e10, 0x3813, 0x3e14, 0x8024, 0x3e04, 0x8024, + 0x2900, 0x48c0, 0x0006, 0x02d3, 0x36e3, 0x0024, 0x3009, 0x1bd3, 0x0007, + 0x8257, 0x3700, 0x8024, 0xf224, 0x0024, 0x0000, 0x0024, 0x2800, 0x2b51, + 0x3600, 0x9844, 0x2900, 0x3100, 0x0000, 0x2bc8, 0x2911, 0xf140, 0x0000, + 0x0024, 0x0030, 0x0057, 0x3700, 0x0024, 0xf200, 0x4595, 0x0fff, 0xfe02, + 0xa024, 0x164c, 0x8000, 0x17cc, 0x3f00, 0x0024, 0x3500, 0x0024, 0x0021, + 0x6d82, 0xd024, 0x44c0, 0x0006, 0xa402, 0x2800, 0x3015, 0xd024, 0x0024, + 0x0000, 0x0000, 0x2800, 0x3015, 0x000b, 0x6d57, 0x3009, 0x3c00, 0x36f0, + 0x8024, 0x36f2, 0x1800, 0x2000, 0x0000, 0x0000, 0x0024, 0x3e14, 0x7810, + 0x3e13, 0xb80d, 0x3e13, 0xf80a, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, + 0xb807, 0x3e14, 0xf801, 0x3e15, 0x3815, 0x0001, 0x000a, 0x0006, 0xc4d7, + 0xbf8e, 0x9c42, 0x3e01, 0x9c03, 0x0006, 0xa017, 0x0023, 0xffd1, 0x0007, + 0x8250, 0x0fff, 0xfd85, 0x3001, 0x0024, 0xa45a, 0x4494, 0x0000, 0x0093, + 0x2800, 0x3751, 0xf25a, 0x104c, 0x34f3, 0x0024, 0x2800, 0x3751, 0x0000, + 0x0024, 0x3413, 0x084c, 0x0000, 0x0095, 0x3281, 0xf806, 0x4091, 0x4d64, + 0x2400, 0x3980, 0x4efa, 0x9c10, 0xf1eb, 0x6061, 0xfe55, 0x2f66, 0x5653, + 0x4d64, 0x48b2, 0xa201, 0x4efa, 0xa201, 0x36f3, 0x3c10, 0x36f5, 0x1815, + 0x36f4, 0xd801, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, + 0xd80a, 0x36f3, 0x980d, 0x2000, 0x0000, 0x36f4, 0x5810, 0x3e12, 0xb817, + 0x3e14, 0xf812, 0x3e01, 0xb811, 0x0007, 0x9717, 0x0020, 0xffd2, 0x0030, + 0x11d1, 0x3111, 0x8024, 0x3704, 0xc024, 0x3b81, 0x8024, 0x3101, 0x8024, + 0x3b81, 0x8024, 0x3f04, 0xc024, 0x2808, 0x4800, 0x36f1, 0x9811, 0x36f3, + 0x0024, 0x3009, 0x3848, 0x3e14, 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, + 0x0001, 0x0010, 0x2915, 0x94c0, 0x0001, 0xcc11, 0x36f0, 0x0024, 0x2927, + 0x9e40, 0x3604, 0x1811, 0x3613, 0x0024, 0x3e14, 0x3811, 0x3e00, 0x0024, + 0x0000, 0x4000, 0x0001, 0x0010, 0x2915, 0x94c0, 0x0001, 0xcc11, 0x36f0, + 0x0024, 0x36f4, 0x1811, 0x3009, 0x1808, 0x2000, 0x0000, 0x0000, 0x190d, + 0x3600, 0x3840, 0x3e13, 0x780e, 0x3e13, 0xf808, 0x3e00, 0x0024, 0x0000, + 0x3fce, 0x0027, 0x9e0f, 0x2922, 0xb680, 0x0000, 0x190d, 0x36f3, 0x0024, + 0x36f3, 0xd808, 0x36f3, 0x580e, 0x2000, 0x0000, 0x3009, 0x1800, 0x3613, + 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, + 0x3e13, 0x7801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, + 0x3811, 0x3e14, 0xb813, 0x3e03, 0xf80e, 0xb488, 0x44d5, 0x3543, 0x134c, + 0x34e5, 0xc024, 0x3524, 0x8024, 0x35a4, 0xc024, 0x3710, 0x8a0c, 0x3540, + 0x4a0c, 0x3d44, 0x8024, 0x3a10, 0x8024, 0x3590, 0x0024, 0x4010, 0x15c1, + 0x6010, 0x3400, 0x3710, 0x8024, 0x2800, 0x5484, 0x3af0, 0x8024, 0x3df0, + 0x0024, 0x3591, 0x4024, 0x3530, 0x4024, 0x4192, 0x4050, 0x6100, 0x1482, + 0x4020, 0x1753, 0xbf8e, 0x1582, 0x4294, 0x4011, 0xbd86, 0x408e, 0x2400, + 0x528e, 0xfe6d, 0x2819, 0x520e, 0x0a00, 0x5207, 0x2819, 0x4fbe, 0x0024, + 0xad56, 0x904c, 0xaf5e, 0x1010, 0xf7d4, 0x0024, 0xf7fc, 0x2042, 0x6498, + 0x2046, 0x3cf4, 0x0024, 0x3400, 0x170c, 0x4090, 0x1492, 0x35a4, 0xc024, + 0x2800, 0x4d15, 0x3c00, 0x0024, 0x4480, 0x914c, 0x36f3, 0xd80e, 0x36f4, + 0x9813, 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, + 0x36f3, 0x5801, 0x3405, 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, + 0x9815, 0x2814, 0x9c91, 0x0000, 0x004d, 0x2814, 0x9940, 0x003f, 0x0013, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, + 0x3e14, 0x3811, 0x0006, 0xa090, 0x2912, 0x0d00, 0x3e14, 0xc024, 0x4088, + 0x8000, 0x4080, 0x0024, 0x0007, 0x90d1, 0x2800, 0x5f85, 0x0000, 0x0024, + 0x0007, 0x9051, 0x3100, 0x4024, 0x4100, 0x0024, 0x3900, 0x0024, 0x0007, + 0x90d1, 0x0004, 0x0000, 0x31f0, 0x4024, 0x6014, 0x0400, 0x0000, 0x0024, + 0x2800, 0x63d1, 0x4080, 0x0024, 0x0000, 0x0000, 0x2800, 0x6345, 0x0000, + 0x0024, 0x0007, 0x9053, 0x3300, 0x0024, 0x4080, 0x0024, 0x0000, 0x0000, + 0x2800, 0x63d8, 0x0000, 0x0024, 0x0007, 0x9051, 0x3900, 0x0024, 0x3200, + 0x504c, 0x6410, 0x0024, 0x3cf0, 0x0000, 0x4080, 0x0024, 0x0006, 0xc691, + 0x2800, 0x7c85, 0x3009, 0x0400, 0x0000, 0x1001, 0x0007, 0x9051, 0x3100, + 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2800, 0x70c9, 0x003f, 0xe000, + 0x0006, 0xc693, 0x3900, 0x0c00, 0x3009, 0x0001, 0x6014, 0x0024, 0x0007, + 0x1ad0, 0x2800, 0x70d5, 0x3009, 0x0000, 0x4080, 0x0024, 0x0000, 0x0301, + 0x2800, 0x6ac5, 0x4090, 0x0024, 0x0000, 0x0024, 0x2800, 0x6bd5, 0x0000, + 0x0024, 0x3009, 0x0000, 0xc012, 0x0024, 0x2800, 0x70c0, 0x3009, 0x2001, + 0x3009, 0x0000, 0x6012, 0x0024, 0x0000, 0x0341, 0x2800, 0x6dd5, 0x0000, + 0x0024, 0x6190, 0x0024, 0x2800, 0x70c0, 0x3009, 0x2000, 0x6012, 0x0024, + 0x0000, 0x0381, 0x2800, 0x6f95, 0x0000, 0x0024, 0x6190, 0x0024, 0x2800, + 0x70c0, 0x3009, 0x2000, 0x6012, 0x0024, 0x0000, 0x00c0, 0x2800, 0x70d5, + 0x0000, 0x0024, 0x3009, 0x2000, 0x0006, 0xa090, 0x3009, 0x0000, 0x4080, + 0x0024, 0x0000, 0x0081, 0x2800, 0x7595, 0x0007, 0x8c13, 0x3300, 0x104c, + 0xb010, 0x0024, 0x0002, 0x8001, 0x2800, 0x7805, 0x34f0, 0x0024, 0x2800, + 0x7580, 0x0000, 0x0024, 0x0006, 0xc351, 0x3009, 0x0000, 0x6090, 0x0024, + 0x3009, 0x2000, 0x2900, 0x0b80, 0x3009, 0x0405, 0x0006, 0xc6d1, 0x0006, + 0xc690, 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, 0x0024, 0x0006, 0xa093, + 0x2800, 0x7411, 0xb880, 0x0024, 0x2800, 0x8540, 0x3009, 0x2c00, 0x4040, + 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2800, 0x8558, 0x0000, 0x0024, + 0x0006, 0xc693, 0x3009, 0x0c00, 0x3009, 0x0001, 0x6014, 0x0024, 0x0006, + 0xc350, 0x2800, 0x8541, 0x0000, 0x0024, 0x6090, 0x0024, 0x3009, 0x2c00, + 0x3009, 0x0005, 0x2900, 0x0b80, 0x0000, 0x8548, 0x3009, 0x0400, 0x4080, + 0x0024, 0x0003, 0x8000, 0x2800, 0x8545, 0x0000, 0x0024, 0x6400, 0x0024, + 0x0000, 0x0081, 0x2800, 0x8549, 0x0000, 0x0024, 0x0007, 0x8c13, 0x3300, + 0x0024, 0xb010, 0x0024, 0x0006, 0xc650, 0x2800, 0x8555, 0x0000, 0x0024, + 0x0001, 0x0002, 0x3413, 0x0000, 0x3009, 0x0401, 0x4010, 0x8406, 0x0000, + 0x0281, 0xa010, 0x13c1, 0x4122, 0x0024, 0x0000, 0x03c2, 0x6122, 0x8002, + 0x462c, 0x0024, 0x469c, 0x0024, 0xfee2, 0x0024, 0x48be, 0x0024, 0x6066, + 0x8400, 0x0006, 0xc350, 0x2800, 0x8541, 0x0000, 0x0024, 0x4090, 0x0024, + 0x3009, 0x2400, 0x2900, 0x0b80, 0x3009, 0x0005, 0x0007, 0x1b50, 0x2912, + 0x0d00, 0x3613, 0x0024, 0x3a00, 0x0380, 0x4080, 0x0024, 0x0000, 0x00c1, + 0x2800, 0x8e05, 0x3009, 0x0000, 0xb010, 0x008c, 0x4192, 0x0024, 0x6012, + 0x0024, 0x0006, 0xf051, 0x2800, 0x8c18, 0x3009, 0x0400, 0x0007, 0x1fd1, + 0x30e3, 0x0400, 0x4080, 0x0024, 0x0000, 0x0301, 0x2800, 0x8e05, 0x3009, + 0x0000, 0xb010, 0x0024, 0x0000, 0x0101, 0x6012, 0x0024, 0x0006, 0xf051, + 0x2800, 0x8e15, 0x0000, 0x0024, 0x3023, 0x0400, 0xf200, 0x184c, 0xb880, + 0xa400, 0x3009, 0x2000, 0x3009, 0x0441, 0x3e10, 0x4402, 0x2909, 0xa9c0, + 0x3e10, 0x8024, 0x36e3, 0x0024, 0x36f4, 0xc024, 0x36f4, 0x1811, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x3801, 0x0000, 0x0081, 0x3e10, 0xb803, 0x3e11, + 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x0006, 0xf250, 0x3e04, 0xb813, + 0x3009, 0x0000, 0x6012, 0x0024, 0x003f, 0xff01, 0x2800, 0x9905, 0x0006, + 0x0611, 0x6194, 0x0400, 0x0000, 0x0041, 0xa020, 0x984c, 0x0000, 0x01c2, + 0xfe02, 0x0024, 0x48b2, 0x0024, 0x3e10, 0x0024, 0x2921, 0xca80, 0x3e00, + 0x4024, 0x3100, 0x5bcc, 0x2921, 0xdd40, 0xb122, 0x0024, 0x291a, 0x8a40, + 0x0000, 0xab08, 0x0007, 0x2052, 0x0006, 0x8a93, 0x3100, 0x184c, 0xa010, + 0x0024, 0x0000, 0x0041, 0x6090, 0x0024, 0x2922, 0x1880, 0x6090, 0x0024, + 0xb880, 0x010c, 0x3100, 0x2800, 0xfe02, 0x8c44, 0x3613, 0x0fc5, 0x4eb2, + 0x0024, 0x3009, 0x2040, 0x0000, 0x00c0, 0x2921, 0xbb80, 0x3e00, 0x23c1, + 0x0000, 0x01c1, 0x6012, 0x0024, 0x0003, 0xf680, 0x2800, 0x9f55, 0x0000, + 0x0024, 0x36f3, 0x0024, 0x291a, 0x8a40, 0x0000, 0xab08, 0x2900, 0x4580, + 0x3e00, 0x0024, 0x3413, 0x0040, 0x36f3, 0x03c1, 0x3009, 0x0c44, 0x3009, + 0x0fc5, 0x6ce2, 0x0024, 0x3c10, 0x0024, 0xbc82, 0x33c1, 0x3410, 0x2040, + 0x34e0, 0x63c1, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2800, 0xa809, 0x4c82, + 0x0024, 0x0000, 0x01c4, 0x4c86, 0x184c, 0x003f, 0xff40, 0xad06, 0x0024, + 0x3e10, 0x8024, 0x2921, 0xca80, 0x3e00, 0xc024, 0x36f3, 0x0024, 0x2921, + 0x9440, 0x0000, 0x0080, 0xb88a, 0x104c, 0x3410, 0x0c46, 0x34e0, 0x4fc7, + 0xbce2, 0x984c, 0x4cf2, 0x0024, 0x3e10, 0x0024, 0x2921, 0x9780, 0x3e00, + 0x4024, 0x2800, 0xaa00, 0x36e3, 0x0024, 0x0000, 0x0024, 0x2800, 0xaa18, + 0x0000, 0x0024, 0x4ce6, 0x184c, 0x3e10, 0x8024, 0x2921, 0x9780, 0x3e00, + 0xc024, 0x36e3, 0x0024, 0x291a, 0x8a40, 0x0000, 0x0100, 0x2922, 0x1880, + 0x3613, 0x0024, 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, + 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, + 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x7802, 0x3e14, 0x0024, 0x2903, 0x9bc0, 0x0000, 0x0201, 0x0000, + 0x0601, 0x3413, 0x184c, 0x2903, 0xa300, 0x3cf0, 0x0024, 0x3413, 0x184c, + 0x3400, 0x3040, 0x3009, 0x33c1, 0x0000, 0x1fc1, 0xb010, 0x0024, 0x6014, + 0x9040, 0x0006, 0x8010, 0x2800, 0xb495, 0x0000, 0x0024, 0x34e3, 0x1bcc, + 0x6890, 0x0024, 0x2800, 0xb640, 0xb880, 0x2000, 0x3e10, 0x1381, 0x2903, + 0xd400, 0x3e00, 0x4024, 0x003f, 0xfe41, 0x36e3, 0x104c, 0x34f0, 0x0024, + 0xa010, 0x0024, 0x36f4, 0x0024, 0x36f0, 0x5802, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x0006, 0x9f97, + 0x3e00, 0x5c15, 0x3009, 0x3840, 0x3009, 0x3814, 0x0025, 0xffd4, 0x0006, + 0xd317, 0x3710, 0x160c, 0x0006, 0x9f94, 0x37f0, 0x73d5, 0x6c92, 0x0024, + 0x3f10, 0x1040, 0x3ff0, 0x53c1, 0x6010, 0x0024, 0x0000, 0x0024, 0x2800, + 0xbc54, 0x0006, 0x0001, 0x4010, 0x0024, 0x0005, 0xf601, 0x6010, 0x9bd4, + 0x0000, 0x0040, 0x2800, 0xbdd4, 0x0030, 0x0497, 0x3f00, 0x0024, 0x2000, + 0x0000, 0x36f0, 0x5800, 0x2a08, 0x1b8e, 0x2803, 0xae80, 0x0000, 0xbe57, + 0x0007, 0x0001, /*copy 1*/ + 0x8300, 0x0006, 0x19f8, /*copy 6648*/ + 0x0030, 0x0055, 0xb080, 0x1402, 0x0fdf, 0xffc1, 0x0007, 0x9257, 0xb212, + 0x3c00, 0x3d00, 0x4024, 0x0006, 0x0097, 0x3f10, 0x0024, 0x3f00, 0x0024, + 0x0030, 0x0297, 0x3f00, 0x0024, 0x0007, 0x9017, 0x3f00, 0x0024, 0x0007, + 0x81d7, 0x3f10, 0x0024, 0xc090, 0x3c00, 0x0006, 0x0297, 0xb080, 0x3c00, + 0x0000, 0x0401, 0x000a, 0x1055, 0x0006, 0x0017, 0x3f10, 0x3401, 0x000a, + 0x2795, 0x3f00, 0x3401, 0x0001, 0x6257, 0xf400, 0x55c0, 0x0000, 0x0817, + 0xb080, 0x57c0, 0x0014, 0x958f, 0x0000, 0x58ce, 0x0030, 0x0017, 0x3700, + 0x0024, 0x0004, 0x0001, 0xb012, 0x0024, 0x0000, 0x004d, 0x280f, 0xe115, + 0x0006, 0x2016, 0x0006, 0x01d7, 0x3f00, 0x0024, 0x0000, 0x190d, 0x000f, + 0xf94f, 0x0000, 0xcd0e, 0x280f, 0xe100, 0x0006, 0x2016, 0x0000, 0x0080, + 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, + 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0007, 0x8a57, 0x3700, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0040, 0x2800, 0xced5, 0x0006, 0xa2d7, 0x3009, + 0x3c00, 0x0006, 0xa157, 0x3009, 0x1c00, 0x0006, 0x01d7, 0x0000, 0x190d, + 0x000a, 0x708f, 0x0000, 0xd7ce, 0x290b, 0x1a80, 0x3f00, 0x184c, 0x0030, + 0x0017, 0x4080, 0x1c01, 0x0000, 0x0200, 0x2800, 0xcb15, 0xb102, 0x0024, + 0x0000, 0xcd08, 0x2800, 0xcb15, 0x0000, 0xd3ce, 0x0011, 0x210f, 0x0000, + 0x190d, 0x280f, 0xcb00, 0x3613, 0x0024, 0x0006, 0xa115, 0x0006, 0x01d7, + 0x37f0, 0x1401, 0x6100, 0x1c01, 0x4012, 0x0024, 0x0000, 0x8000, 0x6010, + 0x0024, 0x34f3, 0x0400, 0x2800, 0xd698, 0x0000, 0x0024, 0x0000, 0x8001, + 0x6010, 0x3c01, 0x0000, 0x000d, 0x2811, 0x8259, 0x0000, 0x0024, 0x2a11, + 0x2100, 0x0030, 0x0257, 0x3700, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2800, 0xd9d5, 0x0006, 0x0197, 0x0006, 0xa115, 0x3f00, 0x3400, 0x4d86, + 0x0024, 0x0000, 0x190d, 0x2800, 0xdd55, 0x0014, 0x1b01, 0x0020, 0x480f, + 0x0000, 0xdc0e, 0x0000, 0x190d, 0x2820, 0x41c0, 0x0001, 0x0948, 0x0039, + 0x324f, 0x0001, 0x364e, 0x2820, 0x4a18, 0xb882, 0x0024, 0x2a20, 0x48c0, + 0x003f, 0xfd00, 0xb700, 0x0024, 0x003f, 0xf901, 0x6010, 0x0024, 0x0000, + 0x0024, 0x280a, 0xc505, 0x0000, 0x190d, 0x0019, 0x9301, 0x2800, 0xdfc0, + 0x0018, 0x50c0, 0x6fc2, 0x0024, 0x0000, 0x0024, 0x2800, 0xe155, 0x0000, + 0x0024, 0x2803, 0x5840, 0x000a, 0xcac8, 0x000a, 0x8c8f, 0x0000, 0xe28e, + 0x000c, 0x0981, 0x280a, 0x71c0, 0x002c, 0x9d40, 0x000a, 0x708f, 0x0000, + 0xd7ce, 0x280a, 0xc0d5, 0x0012, 0x5182, 0x6fd6, 0x0024, 0x003f, 0xfd81, + 0x280a, 0x8e45, 0xb710, 0x0024, 0x003f, 0xf800, 0xb600, 0x0024, 0x0015, + 0xb801, 0x6012, 0x0024, 0x003f, 0xfd81, 0x2801, 0xbac5, 0x0001, 0x0a48, + 0xb710, 0x0024, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, + 0x0015, 0xffd2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x190d, + 0x2801, 0x0015, 0x0030, 0x0250, 0xb880, 0x104c, 0x3cf0, 0x0024, 0x0010, + 0x5500, 0xb880, 0x23c0, 0xb882, 0x2000, 0x0007, 0x8590, 0x2914, 0xbec0, + 0x0000, 0x0440, 0x0007, 0x8b50, 0xb880, 0x0024, 0x2920, 0x0100, 0x3800, + 0x0024, 0x2920, 0x0000, 0x0006, 0x8a91, 0x0000, 0x0800, 0xb880, 0xa440, + 0x003f, 0xfd81, 0xb710, 0xa7c0, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, + 0x0101, 0x2801, 0x0955, 0x0000, 0x0024, 0xffe2, 0x0024, 0x48b2, 0x0024, + 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, 0x0955, 0x0000, 0x0024, 0x2912, + 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, 0x0006, 0x8a90, 0x2801, 0x0955, + 0x0000, 0x01c2, 0xb886, 0x8040, 0x3613, 0x03c1, 0xbcd2, 0x0024, 0x0030, + 0x0011, 0x2800, 0xf5d5, 0x003f, 0xff42, 0xb886, 0x8040, 0x3009, 0x03c1, + 0x0000, 0x0020, 0xac22, 0x0024, 0x0000, 0x0102, 0x6cd2, 0x0024, 0x3e10, + 0x0024, 0x2909, 0x8c80, 0x3e00, 0x4024, 0x36f3, 0x0024, 0x3e11, 0x8024, + 0x3e01, 0xc024, 0x2901, 0x2d00, 0x0000, 0x0201, 0xf400, 0x4512, 0x2900, + 0x0c80, 0x3213, 0x1b8c, 0x3100, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, + 0x2801, 0x0955, 0x0000, 0x0024, 0x291a, 0x8a40, 0x0000, 0x0100, 0x2920, + 0x0200, 0x3633, 0x0024, 0x2920, 0x0280, 0x0000, 0x0401, 0x408e, 0x0024, + 0x2920, 0x0280, 0x0000, 0x0401, 0x003f, 0xfd81, 0xb710, 0x4006, 0x003f, + 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, 0x0955, 0x0000, 0x0024, + 0xffe2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, + 0x0955, 0x0000, 0x0024, 0x2912, 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, + 0x0000, 0x01c2, 0x2800, 0xf1c5, 0x0006, 0x8a90, 0x2a01, 0x0940, 0x2920, + 0x0100, 0x0000, 0x0401, 0x0000, 0x0180, 0x2920, 0x0200, 0x3613, 0x0024, + 0x2920, 0x0280, 0x3613, 0x0024, 0x0000, 0x0401, 0x2920, 0x0280, 0x4084, + 0x984c, 0x0019, 0x9d01, 0x6212, 0x0024, 0x001e, 0x5c01, 0x2801, 0x0495, + 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x0685, 0x0000, 0x0024, 0x001b, + 0x5bc1, 0x6212, 0x0024, 0x001b, 0xdd81, 0x2801, 0x0a55, 0x6012, 0x0024, + 0x0000, 0x0024, 0x2801, 0x0a55, 0x0000, 0x0024, 0x0000, 0x004d, 0x000a, + 0xbf4f, 0x280a, 0xb880, 0x0001, 0x078e, 0x0020, 0xfb4f, 0x0000, 0x190d, + 0x0001, 0x0e8e, 0x2920, 0xf440, 0x3009, 0x2bc1, 0x291a, 0x8a40, 0x36e3, + 0x0024, 0x0000, 0x190d, 0x000a, 0x708f, 0x280a, 0xcac0, 0x0000, 0xd7ce, + 0x0030, 0x0017, 0x3700, 0x4024, 0x0000, 0x0200, 0xb102, 0x0024, 0x0000, + 0x00c0, 0x2801, 0x0d85, 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, + 0x0006, 0x0197, 0x0006, 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0000, + 0x190d, 0x000a, 0x708f, 0x280a, 0xc0c0, 0x0000, 0xd7ce, 0x0000, 0x004d, + 0x0020, 0xfe0f, 0x2820, 0xfb40, 0x0001, 0x0f8e, 0x2801, 0x1155, 0x3009, + 0x1000, 0x6012, 0x93cc, 0x0000, 0x0024, 0x2801, 0x2c05, 0x0000, 0x0024, + 0x3413, 0x0024, 0x34b0, 0x0024, 0x4080, 0x0024, 0x0000, 0x0200, 0x2801, + 0x1455, 0xb882, 0x0024, 0x3453, 0x0024, 0x3009, 0x13c0, 0x4080, 0x0024, + 0x0000, 0x0200, 0x2801, 0x2c05, 0x0000, 0x0024, 0xb882, 0x130c, 0x0000, + 0x004d, 0x0021, 0x058f, 0x2821, 0x0340, 0x0001, 0x154e, 0x2801, 0x2595, + 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x2595, 0x0000, 0x0024, 0x34c3, + 0x184c, 0x3e13, 0xb80f, 0xf400, 0x4500, 0x0026, 0x9dcf, 0x0001, 0x194e, + 0x0000, 0xfa0d, 0x2926, 0x8e80, 0x3e10, 0x110c, 0x36f3, 0x0024, 0x2801, + 0x2580, 0x36f3, 0x980f, 0x001c, 0xdd00, 0x001c, 0xd901, 0x6ec2, 0x0024, + 0x001c, 0xdd00, 0x2801, 0x1c55, 0x0018, 0xdbc1, 0x3413, 0x184c, 0xf400, + 0x4500, 0x2926, 0xc640, 0x3e00, 0x13cc, 0x2801, 0x2340, 0x36f3, 0x0024, + 0x6ec2, 0x0024, 0x003f, 0xc000, 0x2801, 0x1ed5, 0x002a, 0x4001, 0x3413, + 0x184c, 0xf400, 0x4500, 0x2926, 0xafc0, 0x3e00, 0x13cc, 0x2801, 0x2340, + 0x36f3, 0x0024, 0xb400, 0x0024, 0xd100, 0x0024, 0x0000, 0x0024, 0x2801, + 0x2345, 0x0000, 0x0024, 0x3613, 0x0024, 0x3e11, 0x4024, 0x2926, 0x8540, + 0x3e01, 0x0024, 0x4080, 0x1b8c, 0x0000, 0x0024, 0x2801, 0x2345, 0x0000, + 0x0024, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0x8e80, 0x3e10, 0x13cc, + 0x36f3, 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, 0x0000, 0x4000, 0x0000, + 0x0021, 0x6d06, 0x0024, 0x3110, 0x8024, 0x2826, 0xa8c4, 0x31f0, 0xc024, + 0x2a26, 0xad00, 0x34c3, 0x184c, 0x3410, 0x8024, 0x3430, 0xc024, 0x0000, + 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, 0x0000, 0x0024, 0x2801, 0x2c14, + 0x4d06, 0x0024, 0x0000, 0x0200, 0x2922, 0x1885, 0x0001, 0x2a88, 0x0000, + 0x0200, 0x3e10, 0x8024, 0x2921, 0xca80, 0x3e00, 0xc024, 0x291a, 0x8a40, + 0x0000, 0x0024, 0x2922, 0x1880, 0x36f3, 0x0024, 0x0000, 0x004d, 0x0021, + 0x0ecf, 0x2821, 0x0bc0, 0x0001, 0x2b8e, 0x2801, 0x0e80, 0x3c30, 0x4024, + 0x0000, 0x190d, 0x0000, 0x3fce, 0x2821, 0x0f80, 0x0027, 0x9e0f, 0x0020, + 0xcd4f, 0x2820, 0xc780, 0x0001, 0x2dce, 0x0006, 0xf017, 0x0000, 0x0015, + 0xb070, 0xbc15, 0x0000, 0x3fce, 0x0027, 0x9e0f, 0x2820, 0xcd80, 0x0000, + 0x190d, 0x3613, 0x0024, 0x3e10, 0xb803, 0x3e14, 0x3811, 0x3e11, 0x3805, + 0x3e00, 0x3801, 0x0007, 0xc390, 0x0006, 0xa011, 0x3010, 0x0444, 0x3050, + 0x4405, 0x6458, 0x0302, 0xff94, 0x4081, 0x0003, 0xffc5, 0x48b6, 0x0024, + 0xff82, 0x0024, 0x42b2, 0x0042, 0xb458, 0x0003, 0x4cd6, 0x9801, 0xf248, + 0x1bc0, 0xb58a, 0x0024, 0x6de6, 0x1804, 0x0006, 0x0010, 0x3810, 0x9bc5, + 0x3800, 0xc024, 0x36f4, 0x1811, 0x36f0, 0x9803, 0x283e, 0x2d80, 0x0fff, + 0xffc3, 0x2801, 0x4400, 0x0000, 0x0024, 0x3413, 0x0024, 0x2801, 0x3805, + 0xf400, 0x4517, 0x2801, 0x3c00, 0x6894, 0x13cc, 0x37b0, 0x184c, 0x6090, + 0x1d51, 0x0000, 0x0910, 0x3f00, 0x060c, 0x3100, 0x4024, 0x6016, 0xb812, + 0x000c, 0x8012, 0x2801, 0x3a91, 0xb884, 0x0024, 0x6894, 0x3002, 0x0000, + 0x028d, 0x003a, 0x5e0f, 0x0001, 0x4c0e, 0x2939, 0xb0c0, 0x3e10, 0x93cc, + 0x4084, 0x9bd2, 0x4282, 0x0024, 0x0000, 0x0040, 0x2801, 0x3e05, 0x4292, + 0x130c, 0x3443, 0x0024, 0x2801, 0x3f45, 0x000c, 0x8390, 0x2a01, 0x42c0, + 0x3444, 0x0024, 0x3073, 0x0024, 0xc090, 0x014c, 0x2801, 0x42c0, 0x3800, + 0x0024, 0x000c, 0x4113, 0xb880, 0x2380, 0x3304, 0x4024, 0x3800, 0x05cc, + 0xcc92, 0x05cc, 0x3910, 0x0024, 0x3910, 0x4024, 0x000c, 0x8110, 0x3910, + 0x0024, 0x39f0, 0x4024, 0x3810, 0x0024, 0x38d0, 0x4024, 0x3810, 0x0024, + 0x38f0, 0x4024, 0x34c3, 0x0024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3063, + 0x0024, 0x3000, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, + 0x4284, 0x0024, 0x3613, 0x0024, 0x2801, 0x4605, 0x6898, 0xb804, 0x0000, + 0x0084, 0x293b, 0x1cc0, 0x3613, 0x0024, 0x000c, 0x8117, 0x3711, 0x0024, + 0x37d1, 0x4024, 0x4e8a, 0x0024, 0x0000, 0x0015, 0x2801, 0x48c5, 0xce9a, + 0x0024, 0x3f11, 0x0024, 0x3f01, 0x4024, 0x000c, 0x8197, 0x408a, 0x9bc4, + 0x3f15, 0x4024, 0x2801, 0x4b05, 0x4284, 0x3c15, 0x6590, 0x0024, 0x0000, + 0x0024, 0x2839, 0x53d5, 0x4284, 0x0024, 0x0000, 0x0024, 0x2801, 0x36d8, + 0x458a, 0x0024, 0x2a39, 0x53c0, 0x003e, 0x2d4f, 0x283a, 0x5ed5, 0x0001, + 0x2f8e, 0x000c, 0x4653, 0x0000, 0x0246, 0xffac, 0x0c01, 0x48be, 0x0024, + 0x4162, 0x4546, 0x6642, 0x4055, 0x3501, 0x8024, 0x0000, 0x0087, 0x667c, + 0x4057, 0x000c, 0x41d5, 0x283a, 0x62d5, 0x3501, 0x8024, 0x667c, 0x1c47, + 0x3701, 0x8024, 0x283a, 0x62d5, 0xc67c, 0x0024, 0x0000, 0x0024, 0x283a, + 0x62c5, 0x0000, 0x0024, 0x2a3a, 0x5ec0, 0x3009, 0x3851, 0x3e14, 0xf812, + 0x3e12, 0xb817, 0x3e11, 0x8024, 0x0006, 0x0293, 0x3301, 0x8024, 0x468c, + 0x3804, 0x0006, 0xa057, 0x2801, 0x5804, 0x0006, 0x0011, 0x469c, 0x0024, + 0x3be1, 0x8024, 0x2801, 0x5815, 0x0006, 0xc392, 0x3311, 0x0024, 0x33f1, + 0x2844, 0x3009, 0x2bc4, 0x0030, 0x04d2, 0x3311, 0x0024, 0x3a11, 0x0024, + 0x3201, 0x8024, 0x003f, 0xfc04, 0xb64c, 0x0fc4, 0xc648, 0x0024, 0x3a01, + 0x0024, 0x3111, 0x1fd3, 0x6498, 0x07c6, 0x868c, 0x2444, 0x0023, 0xffd2, + 0x3901, 0x8e06, 0x0030, 0x0551, 0x3911, 0x8e06, 0x3961, 0x9c44, 0xf400, + 0x44c6, 0xd46c, 0x1bc4, 0x36f1, 0xbc13, 0x2801, 0x6195, 0x36f2, 0x9817, + 0x002b, 0xffd2, 0x3383, 0x188c, 0x3e01, 0x8c06, 0x0006, 0xa097, 0x3009, + 0x1c12, 0x3213, 0x0024, 0x468c, 0xbc12, 0x002b, 0xffd2, 0xf400, 0x4197, + 0x2801, 0x5e84, 0x3713, 0x0024, 0x2801, 0x5ec5, 0x37e3, 0x0024, 0x3009, + 0x2c17, 0x3383, 0x0024, 0x3009, 0x0c06, 0x468c, 0x4197, 0x0006, 0xa052, + 0x2801, 0x60c4, 0x3713, 0x2813, 0x2801, 0x6105, 0x37e3, 0x0024, 0x3009, + 0x2c17, 0x36f1, 0x8024, 0x36f2, 0x9817, 0x36f4, 0xd812, 0x2100, 0x0000, + 0x3904, 0x5bd1, 0x2a01, 0x51ce, 0x3e11, 0x7804, 0x0030, 0x0257, 0x3701, + 0x0024, 0x0013, 0x4d05, 0xd45b, 0xe0e1, 0x0007, 0xc795, 0x2801, 0x6915, + 0x0fff, 0xff45, 0x3511, 0x184c, 0x4488, 0xb808, 0x0006, 0x8a97, 0x2801, + 0x68c5, 0x3009, 0x1c40, 0x3511, 0x1fc1, 0x0000, 0x0020, 0xac52, 0x1405, + 0x6ce2, 0x0024, 0x0000, 0x0024, 0x2801, 0x68c1, 0x68c2, 0x0024, 0x291a, + 0x8a40, 0x3e10, 0x0024, 0x2921, 0xca80, 0x3e00, 0x4024, 0x36f3, 0x0024, + 0x3009, 0x1bc8, 0x36f0, 0x1801, 0x3601, 0x5804, 0x3e13, 0x780f, 0x3e13, + 0xb808, 0x0008, 0x9b0f, 0x0001, 0x6bce, 0x2908, 0x9300, 0x0000, 0x004d, + 0x36f3, 0x9808, 0x2000, 0x0000, 0x36f3, 0x580f, 0x0007, 0x81d7, 0x3711, + 0x8024, 0x3711, 0xc024, 0x3700, 0x0024, 0x0000, 0x2001, 0xb012, 0x0024, + 0x0034, 0x0000, 0x2801, 0x6f05, 0x0000, 0x01c1, 0x0030, 0x0117, 0x3f00, + 0x0024, 0x0014, 0xc000, 0x0000, 0x01c1, 0x4fce, 0x0024, 0xffea, 0x0024, + 0x48b6, 0x0024, 0x4384, 0x4097, 0xb886, 0x45c6, 0xfede, 0x0024, 0x4db6, + 0x0024, 0x466c, 0x0024, 0x0006, 0xc610, 0x8dd6, 0x8007, 0x0000, 0x00c6, + 0xff6e, 0x0024, 0x48b2, 0x0024, 0x0034, 0x2406, 0xffee, 0x0024, 0x2914, + 0xaa80, 0x40b2, 0x0024, 0xf1c6, 0x0024, 0xf1d6, 0x0024, 0x0000, 0x0201, + 0x8d86, 0x0024, 0x61de, 0x0024, 0x0006, 0xc612, 0x2801, 0x7581, 0x0006, + 0xc713, 0x4c86, 0x0024, 0x2912, 0x1180, 0x0006, 0xc351, 0x0006, 0x0210, + 0x2912, 0x0d00, 0x3810, 0x984c, 0xf200, 0x2043, 0x2808, 0xa000, 0x3800, + 0x0024, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, + 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, + 0x7810, 0x3e14, 0x7812, 0x3e14, 0xc024, 0x2922, 0x1880, 0x0000, 0x0180, + 0x2921, 0xdd40, 0x6892, 0x184c, 0x4080, 0x0024, 0x0000, 0x0024, 0x2801, + 0x7cc5, 0x0000, 0x0024, 0x2801, 0xb840, 0xb880, 0x0024, 0x2921, 0xdd40, + 0x6892, 0x184c, 0x4080, 0x0024, 0x0000, 0x0181, 0x2801, 0x7ed5, 0x0000, + 0x0024, 0x2801, 0xb840, 0xb880, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0101, 0x2801, 0x80c5, 0x0000, 0x0024, 0x2801, + 0xb840, 0xb880, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x4080, 0x0024, + 0x0000, 0x00c1, 0x2801, 0x82c5, 0x0000, 0x0024, 0x2801, 0xb840, 0xb880, + 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x4080, 0x0024, 0x0000, 0x0141, + 0x2801, 0x84c5, 0x0006, 0xf250, 0x2801, 0xb840, 0xb880, 0x0024, 0x2921, + 0xdd40, 0x3613, 0x0024, 0x0000, 0x0101, 0x2921, 0xdd40, 0x3613, 0x2000, + 0x0000, 0x03c1, 0x6012, 0x03cc, 0x3613, 0x2000, 0x2801, 0x8a15, 0x0006, + 0xf051, 0x3009, 0x3841, 0x2921, 0xdd40, 0x0000, 0x0201, 0xb080, 0x024c, + 0x3009, 0x2000, 0x2921, 0xdd40, 0x0000, 0x0401, 0x3009, 0x0401, 0xc100, + 0x0024, 0x2801, 0x8b40, 0x3009, 0x2400, 0x3009, 0x0002, 0x2920, 0x5d00, + 0x3e00, 0x8024, 0x36f3, 0x024c, 0x3009, 0x2000, 0x0000, 0x0101, 0x2921, + 0xdd40, 0x3613, 0x0024, 0x0000, 0x0141, 0x3013, 0x0024, 0x3009, 0x21c0, + 0x3009, 0x0000, 0x6012, 0x0024, 0x0007, 0x1b51, 0x2801, 0x9c95, 0x0000, + 0x0101, 0x0007, 0xc251, 0x2921, 0xdd40, 0x3613, 0x0024, 0x0000, 0x03c1, + 0x6012, 0x2400, 0x3100, 0x984c, 0x2801, 0x93d5, 0x0007, 0xc292, 0x3009, + 0x3841, 0x2921, 0xdd40, 0x0000, 0x0201, 0x4082, 0x044c, 0xb080, 0x0024, + 0x3910, 0x0024, 0x39f0, 0x7841, 0x2921, 0xdd40, 0x0000, 0x0401, 0x3211, + 0x1bcc, 0xb182, 0x0bc5, 0xcec2, 0x0024, 0x3a10, 0x0024, 0x2801, 0x9500, + 0x3af0, 0x4024, 0x2920, 0x5d00, 0x3e00, 0x8024, 0x36f3, 0x044c, 0x3910, + 0x0024, 0x39f0, 0x4024, 0x0007, 0x1b52, 0x0000, 0x0141, 0x2921, 0xdd40, + 0x3613, 0x0024, 0x3111, 0x2240, 0xb880, 0x03cc, 0x31f1, 0x6800, 0xb182, + 0x8000, 0x6ce6, 0x0024, 0x002e, 0xe002, 0x2801, 0xa385, 0xb886, 0x0024, + 0x6de2, 0x0b8c, 0x0000, 0x00c1, 0x2801, 0x9b51, 0x3009, 0x0800, 0xb010, + 0x0024, 0x4192, 0x0024, 0x6012, 0x0024, 0x0007, 0x1b52, 0x2801, 0x9b58, + 0x0000, 0x0024, 0x6890, 0xa004, 0x2801, 0xa380, 0x3009, 0x2800, 0x4e82, + 0x0024, 0x0000, 0x0020, 0xf2c2, 0x0024, 0x2801, 0xa380, 0x3009, 0x2000, + 0x3009, 0x07c0, 0x4080, 0x0024, 0x0000, 0x0024, 0x2801, 0xa385, 0x0000, + 0x0024, 0x3093, 0x0400, 0x4080, 0x03cc, 0x0017, 0x7001, 0x2801, 0xa295, + 0x3009, 0x0000, 0x6012, 0x0024, 0x0007, 0x1b50, 0x2801, 0xa201, 0xb880, + 0x0024, 0x0000, 0x00c1, 0x31f3, 0x0024, 0x3009, 0x0400, 0xb010, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0000, 0x2801, 0xa289, 0x0000, 0x0024, 0x2801, + 0xa380, 0x3009, 0x2000, 0x0006, 0xf050, 0x3009, 0x0000, 0x4000, 0x0024, + 0x3009, 0x2000, 0x0000, 0x0081, 0x0006, 0xf250, 0x3009, 0x0000, 0x6012, + 0x0024, 0x0007, 0xc151, 0x2801, 0xa5c5, 0x0000, 0x0024, 0x2801, 0xb840, + 0xb880, 0x0024, 0x2921, 0xdd40, 0x6892, 0x184c, 0x6892, 0x2400, 0x2921, + 0xdd40, 0x3009, 0x184c, 0x4080, 0x0024, 0x0000, 0x0381, 0x2801, 0xa885, + 0x0000, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x2921, 0xdd40, 0x6892, + 0x184c, 0x4080, 0x0024, 0x0000, 0x0240, 0x2801, 0xab05, 0x0000, 0x00c1, + 0x2921, 0xdd40, 0x6892, 0x184c, 0x0000, 0x00c1, 0x0000, 0x0240, 0x0006, + 0x0592, 0x2922, 0x1880, 0x3613, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, + 0x4080, 0x2800, 0x0000, 0x0201, 0x2801, 0xae15, 0x3613, 0x0024, 0x2921, + 0xdd40, 0x0001, 0xb088, 0x3613, 0x0024, 0x4090, 0x1bcc, 0x0000, 0x0241, + 0x2801, 0xb015, 0x0006, 0x0613, 0x2921, 0xdd40, 0x3613, 0x0024, 0x2801, + 0xb080, 0x3b00, 0x0024, 0x2801, 0xb840, 0xb880, 0x0024, 0x0006, 0x0653, + 0xb880, 0x184c, 0x2921, 0xdd40, 0x6892, 0x2c00, 0x4080, 0x0024, 0x0006, + 0x0650, 0x2801, 0xb605, 0x0000, 0x4003, 0x3000, 0x184c, 0xff86, 0x0024, + 0x48b6, 0x0024, 0x2921, 0xdd40, 0x6892, 0x2002, 0x0000, 0x0201, 0x2921, + 0xdd40, 0x4088, 0x184c, 0x3000, 0x4024, 0x4100, 0x0024, 0x4488, 0x2000, + 0x0000, 0x4003, 0x2801, 0xb295, 0x0006, 0x0650, 0x2921, 0xdd40, 0x6892, + 0x184c, 0x4080, 0x0024, 0x0000, 0x0201, 0x2801, 0xb805, 0x0000, 0x0024, + 0x2921, 0xdd40, 0x3613, 0x0024, 0x6890, 0x0024, 0x36f4, 0xc024, 0x36f4, + 0x5812, 0x36f1, 0x5810, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e14, 0x3811, 0x0006, + 0x8a91, 0x0006, 0x05d0, 0x3e14, 0xb813, 0x0007, 0x8b52, 0x3e13, 0xf80e, + 0x3e03, 0x504c, 0xb880, 0x0024, 0x3c00, 0x33c0, 0x2921, 0xb380, 0x3800, + 0x0024, 0x2920, 0x6a00, 0x0030, 0x0253, 0x0000, 0x0400, 0xb882, 0xa440, + 0xb880, 0xa7c1, 0x3a00, 0x0024, 0x0013, 0x1040, 0x3b00, 0x0024, 0x0000, + 0x0180, 0x2922, 0x1880, 0x3613, 0x0024, 0x4f82, 0x0024, 0x003f, 0xf801, + 0xb010, 0x0024, 0x0015, 0xb801, 0x6012, 0x0024, 0x0007, 0x8a50, 0x2801, + 0xdfd5, 0x0000, 0x0201, 0x0006, 0x8a90, 0x2921, 0xdd40, 0x3613, 0x0024, + 0x003f, 0xfe00, 0x3613, 0x0042, 0xb882, 0x83c3, 0xbdc2, 0x0024, 0x3009, + 0x2040, 0x2921, 0xdd40, 0x6892, 0xa3c1, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2801, 0xca95, 0x0000, 0x0024, 0x2901, 0x7780, 0x0006, 0x05d1, 0x4080, + 0x2400, 0x0006, 0xf052, 0x2801, 0xca85, 0x0000, 0x0024, 0x3613, 0x0841, + 0x3e10, 0x4802, 0x2909, 0xa9c0, 0x3e10, 0x8024, 0x36e3, 0x0024, 0x0006, + 0x05d1, 0x3100, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2921, 0xc305, + 0x0001, 0xdb48, 0x0006, 0x0592, 0xb880, 0x104c, 0x3613, 0x33c0, 0x2922, + 0x1880, 0x0000, 0x0100, 0x3200, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2900, 0x90d5, 0x0001, 0xd3c8, 0x0006, 0x0613, 0xb880, 0x0024, 0x0006, + 0x0610, 0x3b00, 0x0024, 0x0000, 0x0201, 0x2921, 0xdd40, 0x3613, 0x0024, + 0x0000, 0x00c1, 0x3423, 0x0024, 0x3c00, 0x0024, 0xa010, 0x0001, 0x4100, + 0x0024, 0x0000, 0x3fc1, 0x3800, 0x0024, 0x34e0, 0x0024, 0x6012, 0x0024, + 0x0006, 0x0610, 0x2801, 0xcf85, 0x0000, 0x0024, 0x2900, 0x90c0, 0x0000, + 0x0024, 0x0006, 0x0650, 0x3000, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2801, 0xdac5, 0x0000, 0x0024, 0xf200, 0x184c, 0xf200, 0x0024, 0xf200, + 0x0024, 0xb182, 0x3840, 0x2921, 0xca80, 0x3e00, 0x4024, 0x0000, 0x01c1, + 0x291a, 0x8a40, 0x36e3, 0x0024, 0xb888, 0x4411, 0x3000, 0x0024, 0xb012, + 0x0024, 0x6410, 0x2001, 0x0000, 0x0024, 0x2801, 0xdac1, 0x0000, 0x0024, + 0x4192, 0x0024, 0x2401, 0xda81, 0x0000, 0x0024, 0x2921, 0xdd40, 0x6892, + 0x184c, 0x6498, 0x0024, 0x2921, 0xc300, 0x0000, 0x0024, 0x291a, 0x8a40, + 0x3413, 0x0024, 0xf400, 0x4512, 0x0030, 0x0010, 0x0000, 0x0201, 0x2900, + 0x0c80, 0x34f3, 0x0024, 0x3000, 0x0024, 0xb010, 0x0024, 0x0000, 0x0100, + 0x2801, 0xec95, 0x0000, 0x0401, 0x2922, 0x1880, 0x3613, 0x0024, 0x2921, + 0xdd40, 0x3613, 0x0024, 0x2801, 0xeac0, 0xb78e, 0x4006, 0x3000, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0024, 0x2801, 0xec89, 0xf292, 0x0024, 0x6012, + 0x904c, 0x0006, 0x05d1, 0x2801, 0xe318, 0x3100, 0x0024, 0x3000, 0x0024, + 0x4090, 0x0024, 0x3800, 0x0024, 0x3100, 0x0024, 0x4080, 0x4512, 0x34f3, + 0x184c, 0x2801, 0xe5d5, 0x0007, 0x0553, 0x36f3, 0x0800, 0x6090, 0x0024, + 0x4080, 0xa800, 0x0000, 0x0024, 0x2801, 0xec88, 0x0000, 0x0024, 0x3009, + 0x184c, 0x0006, 0xf312, 0x4ffe, 0xb841, 0x2921, 0xdd40, 0x6892, 0x41c7, + 0xb182, 0x9bcc, 0x291a, 0x8a40, 0xcfce, 0x0024, 0x0004, 0x0001, 0xb880, + 0x010c, 0x6890, 0x2000, 0x0007, 0x80d0, 0xb880, 0xa800, 0x3000, 0x2c00, + 0x0007, 0x1ad0, 0xff82, 0x0024, 0x48b2, 0x0024, 0xf400, 0x4040, 0x0000, + 0x03c1, 0xb010, 0x0024, 0x3009, 0x2000, 0x0000, 0x0201, 0x0030, 0x0010, + 0x3000, 0x0024, 0xb010, 0x0024, 0x0000, 0x0180, 0x2801, 0xc1c5, 0x0000, + 0x0024, 0x6890, 0x1bcd, 0x36f3, 0xd80e, 0x36f4, 0x9813, 0x36f4, 0x1811, + 0x36f0, 0xd804, 0x36f0, 0x5802, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, + 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, + 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, + 0xb804, 0x3e01, 0x534c, 0xbe8a, 0x10c0, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2801, 0xf6c5, 0x0000, 0x0024, 0x2903, 0xa300, 0x4082, 0x184c, 0x4c8a, + 0x134c, 0x0000, 0x0001, 0x6890, 0x10c2, 0x4294, 0x0024, 0xac22, 0x0024, + 0xbec2, 0x0024, 0x0000, 0x0024, 0x2801, 0xf6c5, 0x0000, 0x0024, 0x6890, + 0x134c, 0xb882, 0x10c2, 0xac22, 0x0024, 0x4c92, 0x0024, 0xdc92, 0x0024, + 0xceca, 0x0024, 0x4e82, 0x1bc5, 0x36f0, 0x9804, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3645, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, + 0x3e14, 0x104c, 0x2903, 0x9bc0, 0x0000, 0x0081, 0x4080, 0x3040, 0x0000, + 0x0101, 0x2801, 0xfdc5, 0x0000, 0x0024, 0x4090, 0x0024, 0x0006, 0x8050, + 0x2802, 0x11d5, 0x0000, 0x0024, 0x2903, 0x9bc0, 0x3613, 0x0024, 0xb880, + 0x3000, 0x2802, 0x0f80, 0x3009, 0x3380, 0x2903, 0x9bc0, 0x4122, 0x10cc, + 0x3cf0, 0x0024, 0x3001, 0x0024, 0x3400, 0x0024, 0x6800, 0x0024, 0xa408, + 0x9040, 0x4080, 0x0024, 0x0000, 0x07c1, 0x2802, 0x0355, 0x6894, 0x1380, + 0x6894, 0x130c, 0x3460, 0x0024, 0x6408, 0x4481, 0x4102, 0x1380, 0xf400, + 0x4052, 0x0000, 0x07c1, 0x34f0, 0xc024, 0x6234, 0x0024, 0x6824, 0x0024, + 0xa122, 0x0024, 0x6014, 0x0024, 0x0000, 0x0141, 0x2802, 0x0a55, 0x0000, + 0x0024, 0x2903, 0x9bc0, 0x3613, 0x0024, 0x2802, 0x08c0, 0xb88a, 0x4002, + 0x2901, 0xef40, 0x3e00, 0x8024, 0x4c8e, 0xa801, 0x0000, 0x0201, 0x3a10, + 0x1bcc, 0x3000, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, 0x2802, 0x0e55, + 0x659a, 0x0024, 0x6540, 0x184c, 0x0030, 0x0010, 0x2802, 0x0648, 0x0000, + 0x0024, 0x2802, 0x0e40, 0x36f3, 0x0024, 0x2802, 0x0d00, 0xb88a, 0x0024, + 0x2903, 0x74c0, 0x34d0, 0x4024, 0x4c8f, 0xa0a1, 0x0000, 0x0201, 0x3000, + 0x084c, 0xb010, 0x0024, 0x0000, 0x0024, 0x2802, 0x0e55, 0x659a, 0x0024, + 0x6540, 0x10cc, 0x0030, 0x0010, 0x2802, 0x0ac8, 0x0000, 0x0024, 0x34d3, + 0x0024, 0x3423, 0x0024, 0xf400, 0x4510, 0x3009, 0x1380, 0x6090, 0x0024, + 0x3009, 0x2000, 0x6892, 0x108c, 0x34f0, 0x9000, 0xa122, 0x984c, 0x6016, + 0x13c1, 0x0000, 0x0102, 0x2801, 0xff08, 0x0006, 0x8150, 0x2802, 0x1240, + 0x3009, 0x1bcc, 0x6890, 0x938c, 0x3800, 0x0024, 0x36f4, 0x0024, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb804, 0x3e11, 0xb807, 0x3e14, + 0x3811, 0x3e04, 0x934c, 0x3430, 0x0024, 0x4080, 0x0024, 0x0000, 0x0206, + 0x2802, 0x1b45, 0x0006, 0x8151, 0x3101, 0x130c, 0xff0c, 0x1102, 0x6408, + 0x0024, 0x4204, 0x0024, 0xb882, 0x4092, 0x1005, 0xfe02, 0x48be, 0x0024, + 0x4264, 0x0024, 0x2903, 0xe080, 0xf400, 0x4090, 0x36f4, 0x8024, 0x36f4, + 0x1811, 0x36f1, 0x9807, 0x36f0, 0x9804, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3675, 0x0024, + 0x3643, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x0000, 0x0181, 0x3e10, + 0xb803, 0x3e11, 0x3806, 0x3e11, 0xf810, 0x3e14, 0x7812, 0x3e13, 0xf80e, + 0x2903, 0x7dc0, 0x3e03, 0x4024, 0x2903, 0x9bc0, 0x4088, 0x184c, 0x3413, + 0x184c, 0x2903, 0x9bc0, 0x6892, 0x3040, 0x4080, 0x3040, 0x0000, 0x0000, + 0x2802, 0x28c5, 0x0000, 0x0024, 0x6890, 0x0024, 0x2903, 0x7dc0, 0x3cd0, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2802, 0x2915, 0x0000, 0x0024, + 0x3433, 0x0024, 0xf400, 0x4510, 0x34d0, 0x0024, 0x6090, 0x0024, 0x2903, + 0x7dc0, 0x3800, 0x0024, 0x4080, 0x10cc, 0xf400, 0x4510, 0x2802, 0x2685, + 0x34d0, 0x0024, 0x2802, 0x2900, 0x0000, 0x0024, 0x3cd0, 0x0024, 0x3433, + 0x0024, 0x34a0, 0x0024, 0xf400, 0x4510, 0x3430, 0x4024, 0x6100, 0x0024, + 0x0000, 0x0341, 0x3840, 0x0024, 0x3000, 0x0024, 0x6012, 0x0024, 0x0006, + 0x0681, 0x2802, 0x4681, 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, + 0x2000, 0x0000, 0x0000, 0x0024, 0x34d3, 0x184c, 0x3430, 0x8024, 0x2901, + 0xef40, 0x3e00, 0x8024, 0x36f3, 0x11cc, 0xb888, 0x104c, 0x3c10, 0x0024, + 0x3c90, 0x4024, 0x2802, 0x3240, 0x34e3, 0x0024, 0x3411, 0x8024, 0x3491, + 0xc024, 0x4f82, 0x128c, 0x3400, 0x4024, 0x4142, 0x0024, 0xf400, 0x4050, + 0x3800, 0x0024, 0x3440, 0x4024, 0x4142, 0x0024, 0x6498, 0x4050, 0x3009, + 0x2007, 0x0006, 0x8150, 0x3000, 0x11cc, 0x6402, 0x104c, 0x0000, 0x0024, + 0x2802, 0x2f88, 0x0000, 0x0024, 0x3493, 0x0024, 0x2802, 0x6240, 0x34f3, + 0x0024, 0x2802, 0x39c0, 0xb888, 0x0024, 0x3430, 0x8024, 0x2901, 0xef40, + 0x3e00, 0x8024, 0x4c8e, 0x130c, 0x3400, 0x5bcc, 0x4142, 0x0024, 0xf400, + 0x4050, 0x3800, 0x0024, 0x3440, 0x4024, 0x4142, 0x0024, 0xf400, 0x4050, + 0x0000, 0x0201, 0x3009, 0x2007, 0x0030, 0x0010, 0x3000, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0024, 0x2802, 0x6255, 0x6498, 0x0024, 0x0006, 0x8150, + 0x3000, 0x134c, 0x6402, 0x984c, 0x0000, 0x0024, 0x2802, 0x3508, 0x0000, + 0x0024, 0x2802, 0x6240, 0x3433, 0x1bcc, 0x0000, 0x0201, 0xb888, 0x104c, + 0x3430, 0x184c, 0x6010, 0x0024, 0x6402, 0x3000, 0x0000, 0x0201, 0x2802, + 0x4258, 0x0030, 0x0010, 0x4090, 0x124c, 0x2402, 0x4140, 0x0000, 0x0024, + 0x3430, 0x8024, 0x2901, 0xef40, 0x3e00, 0x8024, 0x4c8e, 0x130c, 0x3400, + 0x4024, 0x4142, 0x0024, 0xf400, 0x4050, 0x3800, 0x0024, 0x3410, 0x4024, + 0x4142, 0x0024, 0x6498, 0x4050, 0x3009, 0x2007, 0x0030, 0x0010, 0x0000, + 0x0201, 0x3473, 0x0024, 0x3490, 0x0024, 0x3e00, 0x13cc, 0x2901, 0xf880, + 0x3444, 0x8024, 0x3000, 0x1bcc, 0xb010, 0x0024, 0x0000, 0x0024, 0x2802, + 0x6255, 0x0000, 0x0024, 0x34c3, 0x184c, 0x3470, 0x0024, 0x3e10, 0x104c, + 0x34c0, 0x4024, 0x2902, 0x14c0, 0x3e00, 0x4024, 0x2802, 0x6240, 0x36e3, + 0x0024, 0x0000, 0x0801, 0x3413, 0x0024, 0x34f0, 0x0024, 0x6012, 0x0024, + 0x0000, 0x07c1, 0x2802, 0x6188, 0x0000, 0x0024, 0x6010, 0x114c, 0xb888, + 0x32c0, 0x6402, 0x0024, 0x0000, 0x0101, 0x2802, 0x4e18, 0x0000, 0x0024, + 0x4090, 0x134c, 0x2402, 0x4d40, 0x3009, 0x184c, 0x3430, 0x8024, 0x2901, + 0xef40, 0x3e00, 0x8024, 0x4c8e, 0x130c, 0x3400, 0x4024, 0x4142, 0x0024, + 0xf400, 0x4050, 0x3800, 0x0024, 0x3410, 0x4024, 0x4142, 0x0024, 0x6498, + 0x4050, 0x3009, 0x2007, 0x0000, 0x0101, 0x3433, 0x1bcc, 0x2903, 0x9bc0, + 0x3613, 0x0024, 0x0000, 0x0141, 0x6090, 0x118c, 0x2903, 0x9bc0, 0x3ca0, + 0x184c, 0x3473, 0x184c, 0xb888, 0x3380, 0x3400, 0x0024, 0x6402, 0x0024, + 0x0000, 0x0201, 0x2802, 0x54d8, 0x0000, 0x0024, 0x4090, 0x104c, 0x2402, + 0x5400, 0x0000, 0x0024, 0x34a0, 0x8024, 0x2901, 0xef40, 0x3e00, 0x8024, + 0x0006, 0x8002, 0x4244, 0x118c, 0x4244, 0x0024, 0x6498, 0x4095, 0x3009, + 0x3440, 0x3009, 0x37c1, 0x0000, 0x0201, 0x34f3, 0x0024, 0x0030, 0x0010, + 0x3490, 0x0024, 0x3e00, 0x138c, 0x2901, 0xf880, 0x3444, 0x8024, 0x3000, + 0x1bcc, 0xb010, 0x0024, 0x0000, 0x0024, 0x2802, 0x6255, 0x4112, 0x0024, + 0x3463, 0x0024, 0x34a0, 0x0024, 0x6012, 0x0024, 0x0006, 0x8111, 0x2802, + 0x5e19, 0x0000, 0x0024, 0x3100, 0x11cc, 0x3490, 0x4024, 0x4010, 0x0024, + 0x0000, 0x0a01, 0x6012, 0x0024, 0x0006, 0x8151, 0x2802, 0x5e18, 0x0000, + 0x0024, 0x3613, 0x114c, 0x3101, 0x3804, 0x3490, 0x8024, 0x6428, 0x138c, + 0x3470, 0x8024, 0x3423, 0x0024, 0x3420, 0xc024, 0x4234, 0x1241, 0x4380, + 0x4092, 0x2903, 0xe080, 0x0006, 0x8010, 0x2802, 0x6240, 0x3009, 0x1bcc, + 0x0006, 0x8151, 0x3613, 0x114c, 0x3101, 0x3804, 0x3490, 0x8024, 0x6428, + 0x138c, 0x3470, 0x8024, 0x3423, 0x0024, 0x3420, 0xc024, 0x4234, 0x1241, + 0x4380, 0x4092, 0x2903, 0xea40, 0x0006, 0x8010, 0x2802, 0x6240, 0x3009, + 0x1bcc, 0x0006, 0x8050, 0x6890, 0x0024, 0x3800, 0x0024, 0x3433, 0x0024, + 0x34d0, 0x0024, 0x4080, 0x0024, 0x0006, 0x8150, 0x2802, 0x67c5, 0x0000, + 0x0024, 0x3000, 0x11cc, 0xb888, 0x10cc, 0x6402, 0x3240, 0x3493, 0x0024, + 0x3444, 0x8024, 0x2802, 0x67d8, 0x4090, 0x0024, 0x2402, 0x6780, 0x0000, + 0x0024, 0x6499, 0x2620, 0xb78e, 0x4001, 0x0000, 0x0000, 0x3433, 0x0024, + 0xcfce, 0x1340, 0xaf0e, 0x0024, 0x3a11, 0xa807, 0x36f3, 0x4024, 0x36f3, + 0xd80e, 0x36f4, 0x5812, 0x36f1, 0xd810, 0x36f1, 0x1806, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, + 0xf804, 0x0000, 0x3fc3, 0x3e11, 0x7806, 0x3e11, 0xf810, 0xbc82, 0x12cc, + 0x3404, 0x0024, 0x3023, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x3454, + 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x2903, 0x9bc0, 0x0000, 0x0201, + 0x0006, 0x9301, 0x4088, 0x134c, 0x3400, 0x8024, 0xd204, 0x0024, 0xb234, + 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x3500, 0x0024, 0x3c30, 0x0024, + 0x0000, 0x2000, 0xb400, 0x0024, 0x0000, 0x3001, 0x2802, 0x7555, 0x0000, + 0x3800, 0x0000, 0x0041, 0xfe42, 0x12cc, 0x48b2, 0x1090, 0x3810, 0x0024, + 0x38f0, 0x4024, 0x2802, 0x9640, 0x3430, 0x0024, 0xb400, 0x0024, 0x6012, + 0x0024, 0x0000, 0x3801, 0x2802, 0x7895, 0x0000, 0x3c00, 0x0000, 0x07c0, + 0x0000, 0x0041, 0xb400, 0x12cc, 0xfe02, 0x1150, 0x48b2, 0x0024, 0x689a, + 0x2040, 0x2802, 0x9500, 0x38f0, 0x4024, 0xb400, 0x0024, 0x6012, 0x0024, + 0x0000, 0x3c01, 0x2802, 0x7c15, 0x0000, 0x3e00, 0x0000, 0x03c0, 0x0000, + 0x0085, 0x4592, 0x12cc, 0xb400, 0x1150, 0xfe02, 0x0024, 0x48b2, 0x0024, + 0x3810, 0x0024, 0x2802, 0x9500, 0x38f0, 0x4024, 0xb400, 0x0024, 0x6012, + 0x0024, 0x0000, 0x3e01, 0x2802, 0x7f95, 0x0000, 0x3f00, 0x0000, 0x01c0, + 0xf20a, 0x12cc, 0xb400, 0x1150, 0xf252, 0x0024, 0xfe02, 0x0024, 0x48b2, + 0x0024, 0x3810, 0x0024, 0x2802, 0x9500, 0x38f0, 0x4024, 0xb400, 0x130c, + 0x6012, 0x0024, 0x0000, 0x3f01, 0x2802, 0x8315, 0x4390, 0x0024, 0x0000, + 0x0041, 0x0000, 0x0105, 0x4590, 0x13cc, 0xb400, 0x1150, 0xfe02, 0x0024, + 0x48b2, 0x0024, 0x3810, 0x0024, 0x2802, 0x9500, 0x38f0, 0x4024, 0xb400, + 0x0024, 0x6012, 0x1100, 0x0000, 0x01c1, 0x2802, 0x8695, 0x0000, 0x0024, + 0x0000, 0x0041, 0x0000, 0x0145, 0x6890, 0x12cc, 0xb400, 0x1150, 0xfe02, + 0x0024, 0x48b2, 0x0024, 0x3810, 0x0024, 0x2802, 0x9500, 0x38f0, 0x4024, + 0x6012, 0x0024, 0x0000, 0x3f81, 0x2802, 0x8915, 0xb430, 0x0024, 0x6012, + 0x0024, 0x0000, 0x0024, 0x2802, 0x8915, 0x0000, 0x0024, 0x2802, 0x9500, + 0x0000, 0x0185, 0x2802, 0x9640, 0xc890, 0x0024, 0x0000, 0x3fc3, 0x0000, + 0x0201, 0x34d3, 0x0024, 0x2903, 0x9bc0, 0x3433, 0x184c, 0x0006, 0x9301, + 0x4088, 0x134c, 0x3400, 0x8024, 0xd204, 0x0024, 0xb234, 0x0024, 0x4122, + 0x0024, 0xf400, 0x4055, 0x0000, 0x2001, 0x3500, 0x0024, 0x3c30, 0x0024, + 0x0000, 0x3000, 0xb400, 0x0024, 0x6012, 0x0024, 0x0000, 0x0182, 0x2802, + 0x8f45, 0x0000, 0x0024, 0x2802, 0x9640, 0xc890, 0x0024, 0x459a, 0x12cc, + 0x3404, 0x0024, 0x3023, 0x0024, 0x3010, 0x0024, 0x30d0, 0x4024, 0xac22, + 0x0046, 0x003f, 0xf982, 0x3011, 0xc024, 0x0000, 0x0023, 0xaf2e, 0x0024, + 0x0000, 0x0182, 0xccf2, 0x0024, 0x0000, 0x0fc6, 0x0000, 0x0047, 0xb46c, + 0x2040, 0xfe6e, 0x23c1, 0x3454, 0x0024, 0x3010, 0x0024, 0x30f0, 0x4024, + 0xac22, 0x0024, 0xccb2, 0x0024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x458a, + 0x134c, 0x0000, 0x0201, 0x2802, 0x8a55, 0x0000, 0x3fc3, 0x3430, 0x0024, + 0x36f1, 0xd810, 0x36f1, 0x5806, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3675, + 0x0024, 0x3633, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, + 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x3e14, 0xb813, 0x3e13, + 0xf80e, 0x3e03, 0x4024, 0x2903, 0xc780, 0x0000, 0x0381, 0x000f, 0xff81, + 0x6012, 0x0024, 0x0000, 0x0401, 0x2802, 0x9f05, 0x0000, 0x0024, 0x0000, + 0x0201, 0x3613, 0x0024, 0x2903, 0x9bc0, 0x0003, 0x5508, 0x003f, 0xfe04, + 0x0006, 0x8090, 0xb880, 0x11cc, 0x3413, 0x184c, 0x3c90, 0x0024, 0x2903, + 0x9bc0, 0x34f3, 0x0024, 0x0006, 0x9301, 0x3473, 0x184c, 0x3c10, 0x0024, + 0x34f0, 0x8024, 0x3400, 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, + 0x3fc3, 0xb234, 0x0024, 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, + 0x3500, 0x0024, 0xd024, 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, 0x6892, + 0x4055, 0x3500, 0x0024, 0x3cf0, 0x0024, 0x34a0, 0x0024, 0xf100, 0x0024, + 0xb010, 0x0024, 0x3c60, 0x0024, 0x34b0, 0x0024, 0xb010, 0x0024, 0x0000, + 0x0201, 0x2903, 0x9bc0, 0x3ce0, 0x0024, 0x0006, 0x9301, 0x3473, 0x184c, + 0x3c10, 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, 0x0024, 0x0000, + 0x3fc3, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x003f, 0xff01, + 0x3500, 0x0024, 0x3cf0, 0x0024, 0x34c0, 0x0024, 0xa010, 0x0024, 0x0000, + 0x03c1, 0x3c40, 0x0024, 0x34d0, 0x0024, 0xb010, 0x0024, 0x0000, 0x0201, + 0x2903, 0x9bc0, 0x3cc0, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, + 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, 0x0024, 0x0000, 0x3fc3, + 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x003f, 0xff01, 0x3500, + 0x0024, 0x3cf0, 0x0024, 0x3400, 0x0024, 0xa010, 0x0024, 0x0000, 0x01c1, + 0x3800, 0x0024, 0x34e0, 0x0024, 0xf100, 0x0024, 0xb010, 0x0024, 0x6892, + 0x3080, 0x34f0, 0x0024, 0xb010, 0x0024, 0x3cb0, 0x0024, 0x3450, 0x0024, + 0x34a0, 0x4024, 0xc010, 0x0024, 0x0000, 0x0181, 0x2802, 0xb585, 0x3000, + 0x0024, 0x6890, 0x03cc, 0x2803, 0x5500, 0x3800, 0x0024, 0x6012, 0x0024, + 0x0000, 0x0201, 0x2802, 0xb718, 0x0000, 0x0024, 0x2802, 0xba00, 0x6090, + 0x004c, 0x6012, 0x0024, 0x0000, 0x0281, 0x2802, 0xb948, 0x6012, 0x0024, + 0x0000, 0x0080, 0x2802, 0xb959, 0x0000, 0x0024, 0x2802, 0xba00, 0x3013, + 0x0024, 0x6890, 0x03cc, 0x2803, 0x5500, 0x3800, 0x0024, 0x0000, 0x0201, + 0x3800, 0x114c, 0x34b0, 0x0024, 0x6012, 0x0024, 0x0006, 0x09c1, 0x2802, + 0xc441, 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, 0x2000, 0x0000, + 0x0000, 0x0024, 0x2802, 0xc440, 0x0000, 0x0024, 0x0000, 0x0200, 0x0006, + 0x8110, 0x2802, 0xc440, 0x3800, 0x0024, 0x0000, 0x0300, 0x0006, 0x8110, + 0x2802, 0xc440, 0x3800, 0x0024, 0x0006, 0x8050, 0x6890, 0x0024, 0x2803, + 0x5500, 0x3800, 0x0024, 0x0000, 0x0400, 0x0006, 0x8110, 0x2802, 0xc440, + 0x3800, 0x0024, 0x0000, 0x0500, 0x0006, 0x8110, 0x2802, 0xc440, 0x3800, + 0x0024, 0x0000, 0x0600, 0x0006, 0x8110, 0x2802, 0xc440, 0x3800, 0x0024, + 0x0006, 0x8050, 0x6890, 0x0024, 0x2803, 0x5500, 0x3800, 0x0024, 0x3423, + 0x184c, 0x3460, 0x0024, 0x4080, 0x0024, 0x0006, 0x8200, 0x2802, 0xc985, + 0x3e10, 0x0024, 0x0000, 0x01c0, 0x3e10, 0x0024, 0x3490, 0x0024, 0x2902, + 0x6ac0, 0x3e00, 0x13cc, 0x36d3, 0x11cc, 0x3413, 0x0024, 0x4080, 0x3240, + 0x34f3, 0x0024, 0x2802, 0xcd58, 0x0000, 0x0024, 0x0006, 0x8010, 0x6890, + 0x0024, 0x2803, 0x5500, 0x3800, 0x0024, 0x0000, 0x0180, 0x3e10, 0x0024, + 0x3490, 0x0024, 0x2902, 0x6ac0, 0x3e00, 0x13cc, 0x36d3, 0x11cc, 0x3413, + 0x0024, 0x4080, 0x3240, 0x34f3, 0x0024, 0x2802, 0xcd58, 0x0000, 0x0024, + 0x0006, 0x8010, 0x6890, 0x0024, 0x2803, 0x5500, 0x3800, 0x0024, 0x0000, + 0x0201, 0x3433, 0x0024, 0x34d0, 0x0024, 0x6012, 0x0024, 0x0006, 0x0bc1, + 0x2802, 0xdf41, 0x4012, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, 0x2000, + 0x0000, 0x0000, 0x0024, 0x0006, 0x8050, 0x6890, 0x0024, 0x2803, 0x5500, + 0x3800, 0x0024, 0x0000, 0x3000, 0x2802, 0xe100, 0x0006, 0x8150, 0x0000, + 0x9000, 0x0006, 0x8150, 0x3433, 0x0024, 0x34d0, 0x4024, 0x4192, 0x0024, + 0x4192, 0x0024, 0x2802, 0xe100, 0xa010, 0x0024, 0x0000, 0x0201, 0x0006, + 0x8150, 0x2903, 0x9bc0, 0x3613, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, + 0x3c10, 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, 0xd234, 0x0024, 0x0000, + 0x3fc3, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x3500, 0x0024, + 0x3cf0, 0x0024, 0x3490, 0x0024, 0x2802, 0xe100, 0x6090, 0x0024, 0x003f, + 0xfe04, 0x0000, 0x0401, 0x0006, 0x8150, 0x2903, 0x9bc0, 0x3613, 0x0024, + 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, 0x0024, 0x34f0, 0x8024, 0x3400, + 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, 0x3fc3, 0xb234, 0x0024, + 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, 0x3500, 0x0024, 0xd024, + 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, 0x4055, 0x3500, 0x0024, + 0x3cf0, 0x0024, 0x3490, 0x0024, 0x2802, 0xe100, 0x6090, 0x0024, 0x0000, + 0x4000, 0x0000, 0x0202, 0x0006, 0x8150, 0x3433, 0x0024, 0x34d0, 0x4024, + 0x6122, 0x0024, 0xa010, 0x0024, 0x0004, 0x8001, 0x3800, 0x110c, 0x0006, + 0x8150, 0x3000, 0x0024, 0x6012, 0x1300, 0x0000, 0x0401, 0x2802, 0xe3c9, + 0x0000, 0x0024, 0x6890, 0x82cc, 0x2803, 0x5500, 0x3800, 0x0024, 0x6012, + 0x0024, 0x0006, 0x0dc1, 0x2803, 0x0b41, 0x4012, 0x0024, 0xf400, 0x4057, + 0x3702, 0x0024, 0x2000, 0x0000, 0x0000, 0x0024, 0x2803, 0x0b40, 0x0000, + 0x0024, 0x0016, 0x2200, 0x0006, 0x8190, 0x6892, 0x2040, 0x2803, 0x0b40, + 0x38f0, 0x4024, 0x002c, 0x4400, 0x0000, 0x0081, 0x0006, 0x8190, 0x3810, + 0x0024, 0x2803, 0x0b40, 0x38f0, 0x4024, 0x003b, 0x8000, 0x0000, 0x0081, + 0x0006, 0x8190, 0x3810, 0x0024, 0x2803, 0x0b40, 0x38f0, 0x4024, 0x0007, + 0xd000, 0x0006, 0x8190, 0xb882, 0x2040, 0x2803, 0x0b40, 0x38f0, 0x4024, + 0x000f, 0xa000, 0x0006, 0x8190, 0xb882, 0x2040, 0x2803, 0x0b40, 0x38f0, + 0x4024, 0x0015, 0x8880, 0x0006, 0x8190, 0xb882, 0x2040, 0x2803, 0x0b40, + 0x38f0, 0x4024, 0x0017, 0x7000, 0x0006, 0x8190, 0xb882, 0x2040, 0x2803, + 0x0b40, 0x38f0, 0x4024, 0x001f, 0x4000, 0x0006, 0x8190, 0xb882, 0x2040, + 0x2803, 0x0b40, 0x38f0, 0x4024, 0x002b, 0x1100, 0x0006, 0x8190, 0xb882, + 0x2040, 0x2803, 0x0b40, 0x38f0, 0x4024, 0x002e, 0xe000, 0x0006, 0x8190, + 0xb882, 0x2040, 0x2803, 0x0b40, 0x38f0, 0x4024, 0x001d, 0xc000, 0x0006, + 0x8190, 0x6892, 0x2040, 0x2803, 0x0b40, 0x38f0, 0x4024, 0x0006, 0x8190, + 0x0000, 0x0201, 0x0000, 0xfa04, 0x2903, 0x9bc0, 0x3613, 0x0024, 0x0006, + 0x9301, 0xb88a, 0x11cc, 0x3c10, 0x0024, 0x34f0, 0x8024, 0x3410, 0xc024, + 0xd234, 0x0024, 0x0000, 0x3fc3, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, + 0x4055, 0x3500, 0x0024, 0x3cf0, 0x0024, 0x3490, 0x0024, 0xfe50, 0x4005, + 0x48b2, 0x0024, 0xfeca, 0x0024, 0x40b2, 0x0024, 0x3810, 0x0024, 0x2803, + 0x0b40, 0x38f0, 0x4024, 0x003f, 0xfe04, 0x0000, 0x0401, 0x0006, 0x8190, + 0x2903, 0x9bc0, 0x3613, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, + 0x0024, 0x34f0, 0x8024, 0x3400, 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, + 0x0000, 0x3fc3, 0xb234, 0x0024, 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, + 0x9301, 0x3500, 0x0024, 0xd024, 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, + 0xf400, 0x4055, 0x0000, 0x0041, 0x3500, 0x0024, 0x3cf0, 0x0024, 0x3490, + 0x0024, 0xfe02, 0x0024, 0x48b2, 0x0024, 0x3810, 0x0024, 0x2803, 0x0b40, + 0x38f0, 0x4024, 0x003f, 0xfe04, 0x0000, 0x0401, 0x0006, 0x8190, 0x2903, + 0x9bc0, 0x3613, 0x0024, 0x0006, 0x9301, 0x3473, 0x0024, 0x3c10, 0x0024, + 0x34f0, 0x8024, 0x3400, 0xc024, 0xa346, 0x0024, 0xd234, 0x0024, 0x0000, + 0x3fc3, 0xb234, 0x0024, 0x4122, 0x1042, 0xf400, 0x4055, 0x0006, 0x9301, + 0x3500, 0x0024, 0xd024, 0x3000, 0xb234, 0x0024, 0x4122, 0x0024, 0xf400, + 0x4055, 0x3500, 0x0024, 0x3cf0, 0x0024, 0x0000, 0x0280, 0x3490, 0x4024, + 0xfe02, 0x0024, 0x48b2, 0x0024, 0x3810, 0x0024, 0x2803, 0x0b40, 0x38f0, + 0x4024, 0x0006, 0x8010, 0x6890, 0x0024, 0x2803, 0x5500, 0x3800, 0x0024, + 0x0000, 0x0201, 0x2903, 0x9bc0, 0x3613, 0x11cc, 0x3c10, 0x0024, 0x3490, + 0x4024, 0x6014, 0x13cc, 0x0000, 0x0081, 0x2803, 0x0e85, 0x0006, 0x80d0, + 0x0006, 0x8010, 0x6890, 0x0024, 0x2803, 0x5500, 0x3800, 0x0024, 0x3000, + 0x0024, 0x6012, 0x0024, 0x0000, 0x0241, 0x2803, 0x1309, 0x0000, 0x0024, + 0x6890, 0x034c, 0xb882, 0x2000, 0x0006, 0x8310, 0x2914, 0xbec0, 0x0000, + 0x1000, 0x0000, 0x0800, 0x3613, 0x0024, 0x3e10, 0x0024, 0x0006, 0x8300, + 0x290c, 0x7300, 0x3e10, 0x0024, 0x2803, 0x5500, 0x36e3, 0x0024, 0x0006, + 0x8110, 0x30e1, 0x184c, 0x3000, 0x0024, 0x6012, 0x0024, 0x0008, 0x0001, + 0x2803, 0x1515, 0x0000, 0x0024, 0x6498, 0x0024, 0x3e10, 0x4024, 0x0000, + 0x0081, 0x2902, 0x1dc0, 0x3e01, 0x0024, 0x36e3, 0x004c, 0x3000, 0x0024, + 0x6012, 0x0024, 0x000b, 0x8011, 0x2803, 0x20d5, 0x0006, 0x8112, 0x0000, + 0x0201, 0x0004, 0x0010, 0x2915, 0x8300, 0x0001, 0x0000, 0x000b, 0x8011, + 0x0005, 0x0010, 0x291f, 0xc6c0, 0x0001, 0x0000, 0x0006, 0x8110, 0x30e1, + 0x0024, 0x3000, 0x0024, 0x6012, 0x0024, 0x0000, 0x0281, 0x2803, 0x1c45, + 0x6012, 0x0024, 0x000b, 0x8001, 0x2803, 0x1cd5, 0x3613, 0x0024, 0x36f3, + 0x0024, 0x000b, 0x8001, 0x6498, 0x184c, 0x0006, 0x8112, 0x0003, 0x8000, + 0x3e10, 0x4024, 0x2902, 0x1dc0, 0x3e01, 0x0024, 0x36f3, 0x0024, 0x3009, + 0x3844, 0x3e10, 0x0024, 0x0000, 0x0400, 0x3000, 0x8024, 0x0008, 0x0010, + 0x3e00, 0x8024, 0x3201, 0x0024, 0x6408, 0x4051, 0x2903, 0x8740, 0x0003, + 0x2388, 0x0000, 0x0400, 0x0000, 0x0011, 0x3613, 0x008c, 0x30d0, 0x7844, + 0x3e10, 0x4024, 0x3000, 0x8024, 0x0008, 0x0010, 0x3e00, 0x8024, 0x3201, + 0x0024, 0x2903, 0x8740, 0x6408, 0x0024, 0x0006, 0x8a10, 0x0000, 0x01c1, + 0x36e3, 0x0000, 0xb010, 0x9bc4, 0x0000, 0x0024, 0x2803, 0x2785, 0x0000, + 0x0024, 0x6192, 0x184c, 0x2903, 0x9bc0, 0x6102, 0x0024, 0x4088, 0x0024, + 0x0000, 0x0024, 0x2803, 0x2785, 0x0000, 0x0024, 0x6890, 0x0b4c, 0x3a00, + 0x0024, 0x0000, 0x0401, 0x2903, 0x9bc0, 0x3613, 0x11cc, 0x3413, 0x0024, + 0x3c90, 0x0024, 0x290b, 0x1400, 0x34f3, 0x0024, 0x4080, 0x0024, 0x0000, + 0x0024, 0x2803, 0x5195, 0x0000, 0x0024, 0x3423, 0x0024, 0x34e0, 0x0024, + 0x4080, 0x0024, 0x0006, 0x8151, 0x2803, 0x2f05, 0x0000, 0x3200, 0x0000, + 0x0142, 0x0006, 0x8211, 0x3613, 0x0024, 0x3e00, 0x7800, 0x3111, 0x8024, + 0x31d1, 0xc024, 0xfef4, 0x4087, 0x48b6, 0x0440, 0xfeee, 0x07c1, 0x2914, + 0xa580, 0x42b6, 0x0024, 0x2803, 0x3300, 0x0007, 0x89d0, 0x0000, 0x0142, + 0x3613, 0x0024, 0x3e00, 0x7800, 0x3131, 0x8024, 0x3110, 0x0024, 0x31d0, + 0x4024, 0xfe9c, 0x4181, 0x48be, 0x0024, 0xfe82, 0x0440, 0x46be, 0x07c1, + 0xfef4, 0x4087, 0x48b6, 0x0024, 0xfeee, 0x0024, 0x2914, 0xa580, 0x42b6, + 0x0024, 0x0007, 0x89d0, 0x0006, 0x8191, 0x4c8a, 0x9800, 0xfed0, 0x4005, + 0x48b2, 0x0024, 0xfeca, 0x0024, 0x40b2, 0x0024, 0x3810, 0x0024, 0x38f0, + 0x4024, 0x3111, 0x8024, 0x468a, 0x0707, 0x2908, 0xbe80, 0x3101, 0x0024, + 0x3123, 0x11cc, 0x3100, 0x108c, 0x3009, 0x3000, 0x0004, 0x8000, 0x3009, + 0x1241, 0x6014, 0x138c, 0x000b, 0x8011, 0x2803, 0x3941, 0x0000, 0x0024, + 0x3473, 0x0024, 0x3423, 0x0024, 0x3009, 0x3240, 0x34e3, 0x0024, 0x2803, + 0x4fc0, 0x0008, 0x0012, 0x0006, 0x80d0, 0x2803, 0x3ac9, 0x0000, 0x0024, + 0xf400, 0x4004, 0x3000, 0x0024, 0x4090, 0x0024, 0xf400, 0x4480, 0x2803, + 0x4095, 0x000b, 0x8001, 0x0000, 0x0005, 0x6540, 0x0024, 0x0000, 0x0024, + 0x2803, 0x4bd8, 0x4490, 0x0024, 0x2403, 0x3fc0, 0x0000, 0x0024, 0x0006, + 0x8301, 0x4554, 0x0800, 0x4122, 0x0024, 0x659a, 0x4055, 0x0006, 0x8341, + 0x4122, 0x3400, 0xf400, 0x4055, 0x3210, 0x0024, 0x3d00, 0x0024, 0x2803, + 0x4bc0, 0x0000, 0x0024, 0x6014, 0x0024, 0x0001, 0x0000, 0x2803, 0x4815, + 0x0000, 0x0005, 0x0008, 0x0012, 0x0008, 0x0010, 0x0003, 0x8001, 0x0006, + 0x8153, 0x3613, 0x0024, 0x3009, 0x3811, 0x2903, 0xfc00, 0x0004, 0x0011, + 0x0008, 0x0010, 0x0001, 0x0000, 0x291f, 0xc6c0, 0x0005, 0x0011, 0x000f, + 0x0011, 0x0008, 0x0010, 0x33d0, 0x184c, 0x6010, 0xb844, 0x3e10, 0x0024, + 0x0000, 0x0400, 0x3320, 0x4024, 0x3e00, 0x4024, 0x3301, 0x0024, 0x2903, + 0x8740, 0x6408, 0x0024, 0x36e3, 0x0024, 0x3009, 0x1bc4, 0x3009, 0x1bd1, + 0x6540, 0x0024, 0x0000, 0x0024, 0x2803, 0x4bd8, 0x4490, 0x0024, 0x2403, + 0x4b80, 0x0000, 0x0024, 0x0006, 0x8301, 0x4554, 0x0840, 0x4122, 0x0024, + 0x659a, 0x4055, 0x0006, 0x8341, 0x4122, 0x3400, 0xf400, 0x4055, 0x3110, + 0x0024, 0x3d00, 0x0024, 0xf400, 0x4510, 0x0030, 0x0013, 0x3073, 0x184c, + 0x3e11, 0x008c, 0x3009, 0x0001, 0x6140, 0x0024, 0x0000, 0x0201, 0x3009, + 0x2000, 0x0006, 0x8300, 0x290c, 0x7300, 0x3e10, 0x0024, 0x3300, 0x1b8c, + 0xb010, 0x0024, 0x0000, 0x0024, 0x2803, 0x5195, 0x0000, 0x0024, 0x3473, + 0x0024, 0x3423, 0x0024, 0x3009, 0x1240, 0x4080, 0x138c, 0x0000, 0x0804, + 0x2803, 0x39d5, 0x6402, 0x0024, 0x0006, 0xd312, 0x0006, 0xd310, 0x0006, + 0x8191, 0x3010, 0x984c, 0x30f0, 0xc024, 0x0000, 0x0021, 0xf2d6, 0x07c6, + 0x290a, 0xf5c0, 0x4682, 0x0400, 0x6894, 0x0840, 0xb886, 0x0bc1, 0xbcd6, + 0x0024, 0x3a10, 0x8024, 0x3af0, 0xc024, 0x36f3, 0x4024, 0x36f3, 0xd80e, + 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, + 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, + 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, + 0x0020, 0x0001, 0x3e14, 0x3811, 0x0030, 0x0050, 0x0030, 0x0251, 0x3e04, + 0xb813, 0x3000, 0x0024, 0xc012, 0x0024, 0x0019, 0x9300, 0x3800, 0x4024, + 0x2903, 0xae40, 0x3900, 0x0024, 0x2903, 0xbb80, 0x0000, 0x0300, 0xb882, + 0x0024, 0x2914, 0xbec0, 0x0006, 0x8010, 0x0000, 0x1540, 0x0007, 0x8190, + 0x2900, 0xadc0, 0x3800, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, + 0x6555, 0x0000, 0x0024, 0x0006, 0x8012, 0x3200, 0x0024, 0x4080, 0x0024, + 0x0030, 0x0010, 0x2803, 0x6555, 0x0000, 0x0201, 0x3000, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0024, 0x2803, 0x6555, 0x0000, 0x0024, 0x2900, 0xadc0, + 0x0000, 0x0024, 0x4080, 0x0024, 0x0006, 0x8010, 0x2803, 0x6555, 0x3000, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0201, 0x2803, 0x6185, 0x0030, 0x0010, + 0x0030, 0x0050, 0xf292, 0x0000, 0xb012, 0x0024, 0x3800, 0x4024, 0x0030, + 0x0010, 0x0000, 0x0201, 0x3000, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, + 0x2900, 0xbe95, 0x0003, 0x6f08, 0x0006, 0x8011, 0x3100, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0024, 0x2803, 0x6d45, 0x0000, 0x0024, 0x0007, 0x8a52, + 0x3200, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2803, 0x6d49, 0x0000, + 0x0024, 0xf292, 0x0800, 0x6012, 0x0024, 0x0000, 0x0000, 0x2803, 0x6d05, + 0x0000, 0x0024, 0x3200, 0x0024, 0x4090, 0x0024, 0xb880, 0x2800, 0x3900, + 0x0024, 0x3100, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2902, 0x9885, + 0x0003, 0x6648, 0x2900, 0xbe80, 0x0000, 0x0024, 0x0000, 0x0010, 0x0006, + 0x9f51, 0x0006, 0x9f92, 0x0030, 0x0493, 0x0000, 0x0201, 0x6890, 0xa410, + 0x3b00, 0x2810, 0x0006, 0x8a10, 0x3009, 0x0000, 0x6012, 0x0024, 0x0006, + 0x9fd0, 0x2803, 0x7288, 0xb880, 0x0024, 0x6890, 0x0024, 0x3009, 0x2000, + 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, + 0x3e10, 0xb810, 0x3e11, 0x3805, 0x3e02, 0x0024, 0x0030, 0x0010, 0xce9a, + 0x0002, 0x0000, 0x0200, 0x2903, 0x7dc0, 0xb024, 0x0024, 0xc020, 0x0024, + 0x0000, 0x0200, 0x2803, 0x7685, 0x6e9a, 0x0002, 0x4182, 0x0024, 0x0000, + 0x0400, 0x2803, 0x7c45, 0xae1a, 0x0024, 0x6104, 0x984c, 0x0000, 0x0024, + 0x2903, 0x9bc9, 0x0003, 0x7c08, 0x6103, 0xe4e5, 0x2903, 0x9bc0, 0x408a, + 0x188c, 0x2903, 0x9bc0, 0x408a, 0x4141, 0x4583, 0x6465, 0x2803, 0x7c40, + 0xceca, 0x1bcc, 0xc408, 0x0024, 0xf2e2, 0x1bc8, 0x36f1, 0x1805, 0x2000, + 0x0011, 0x36f0, 0x9810, 0x2000, 0x0000, 0xdc92, 0x0024, 0x0006, 0x8a17, + 0x3613, 0x1c00, 0x6093, 0xe1e3, 0x0000, 0x03c3, 0x0006, 0x9f95, 0xb132, + 0x9415, 0x3500, 0xfc01, 0x2803, 0x8695, 0xa306, 0x0024, 0x3009, 0x184c, + 0x3009, 0x3814, 0x0025, 0xffd4, 0x0006, 0xd317, 0x3710, 0x160c, 0x0006, + 0x9f94, 0x37f0, 0x73d5, 0x6c92, 0x3808, 0x3f10, 0x0024, 0x3ff0, 0x4024, + 0x3009, 0x1040, 0x3009, 0x13c1, 0x6010, 0x0024, 0x0000, 0x0024, 0x2903, + 0xc445, 0x0003, 0x8288, 0x2803, 0x84d4, 0x0006, 0x0001, 0x4010, 0x0024, + 0x0005, 0xf601, 0x6010, 0x0024, 0x0000, 0x0040, 0x2803, 0x8654, 0x0030, + 0x0497, 0x3f00, 0x0024, 0x36f2, 0x1814, 0x4330, 0x9803, 0x2000, 0x0000, + 0x8880, 0x1bc1, 0x3613, 0x0024, 0x3e22, 0xb806, 0x3e05, 0xb814, 0x3615, + 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x7807, + 0x6848, 0x930c, 0x3411, 0x780d, 0x459a, 0x10c0, 0x0000, 0x0201, 0x6012, + 0x384e, 0x0000, 0x0241, 0x2803, 0x8dd5, 0x6012, 0x380f, 0x2403, 0x8d05, + 0x0000, 0x0024, 0x3000, 0x0001, 0x3101, 0x8407, 0x6cfe, 0x0024, 0xac42, + 0x0024, 0xaf4e, 0x2040, 0x3911, 0x8024, 0x2803, 0x9980, 0x0000, 0x0024, + 0x0000, 0x0281, 0x2803, 0x9115, 0x6012, 0x4455, 0x2403, 0x9045, 0x0000, + 0x0024, 0x3000, 0x0001, 0x3101, 0x8407, 0x4cf2, 0x0024, 0xac42, 0x0024, + 0xaf4e, 0x2040, 0x3911, 0x8024, 0x2803, 0x9980, 0x0000, 0x0024, 0x0000, + 0x0024, 0x2803, 0x9555, 0x4080, 0x0024, 0x3110, 0x0401, 0xf20f, 0x0203, + 0x2403, 0x9485, 0x8dd6, 0x0024, 0x4dce, 0x0024, 0xf1fe, 0x0024, 0xaf4e, + 0x0024, 0x6dc6, 0x2046, 0xf1df, 0x0203, 0xaf4f, 0x1011, 0xf20e, 0x07cc, + 0x8dd6, 0x2486, 0x2803, 0x9980, 0x0000, 0x0024, 0x0000, 0x0024, 0x2803, + 0x97d5, 0x0000, 0x0024, 0x0fff, 0xffd1, 0x2403, 0x9705, 0x3010, 0x0001, + 0xac4f, 0x0801, 0x3821, 0x8024, 0x2803, 0x9980, 0x0000, 0x0024, 0x0fff, + 0xffd1, 0x2403, 0x9945, 0x3010, 0x0001, 0x3501, 0x9407, 0xac47, 0x0801, + 0xaf4e, 0x2082, 0x3d11, 0x8024, 0x36f3, 0xc024, 0x36f3, 0x980d, 0x36f1, + 0x5807, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36e3, 0x0024, + 0x2000, 0x0000, 0x36f2, 0x9806, 0x3e10, 0xb812, 0x3e11, 0xb810, 0x3e12, + 0x0024, 0x0006, 0x9f92, 0x0025, 0xffd0, 0x3e04, 0x4bd1, 0x3181, 0xf847, + 0xb68c, 0x4440, 0x3009, 0x0802, 0x6024, 0x3806, 0x0006, 0x8a10, 0x2903, + 0xc445, 0x0003, 0x9dc8, 0x0000, 0x0800, 0x6101, 0x1602, 0xaf2e, 0x0024, + 0x4214, 0x1be3, 0xaf0e, 0x1811, 0x0fff, 0xfc00, 0xb200, 0x9bc7, 0x0000, + 0x03c0, 0x2803, 0xa205, 0xb204, 0xa002, 0x2900, 0xb800, 0x3613, 0x2002, + 0x4680, 0x1bc8, 0x36f1, 0x9810, 0x2000, 0x0000, 0x36f0, 0x9812, 0x0000, + 0x0400, 0x6102, 0x0024, 0x3e11, 0x3805, 0x2803, 0xa609, 0x3e02, 0x0024, + 0x2903, 0x9bc0, 0x408a, 0x188c, 0x2903, 0x9bc0, 0x408a, 0x4141, 0x4582, + 0x1bc8, 0x2000, 0x0000, 0x36f1, 0x1805, 0x2903, 0x9bc0, 0x4102, 0x184c, + 0xb182, 0x1bc8, 0x2000, 0x0000, 0x36f1, 0x1805, 0x2a03, 0xa78e, 0x3e12, + 0xb817, 0x3e10, 0x3802, 0x0000, 0x800a, 0x0006, 0x9f97, 0x3009, 0x1fc2, + 0x3e04, 0x5c00, 0x6020, 0xb810, 0x0030, 0x0451, 0x2803, 0xaa54, 0x0006, + 0x0002, 0x4020, 0x0024, 0x0005, 0xfb02, 0x6024, 0x0024, 0x0025, 0xffd0, + 0x2803, 0xac91, 0x3100, 0x1c11, 0xb284, 0x0024, 0x0030, 0x0490, 0x3800, + 0x8024, 0x0025, 0xffd0, 0x3980, 0x1810, 0x36f4, 0x7c11, 0x36f0, 0x1802, + 0x0030, 0x0717, 0x3602, 0x8024, 0x2100, 0x0000, 0x3f05, 0xdbd7, 0x0003, + 0xa757, 0x3613, 0x0024, 0x3e00, 0x3801, 0xf400, 0x55c0, 0x0000, 0x0897, + 0xf400, 0x57c0, 0x0000, 0x0024, 0x2000, 0x0000, 0x36f0, 0x1801, 0x3613, + 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb803, 0xb884, 0xb805, 0xb88a, 0x3844, 0x3e11, + 0xb80d, 0x3e03, 0xf80e, 0x0000, 0x03ce, 0x2403, 0xb68e, 0xf400, 0x4083, + 0x0000, 0x0206, 0xa562, 0x0024, 0x455a, 0x0024, 0x0020, 0x0006, 0xd312, + 0x0024, 0xb16c, 0x0024, 0x0000, 0x01c6, 0x2803, 0xb685, 0x0000, 0x0024, + 0xd56a, 0x0024, 0x4336, 0x0024, 0x0000, 0x4000, 0x0006, 0x9306, 0x4092, + 0x0024, 0xb512, 0x0024, 0x462c, 0x0024, 0x6294, 0x4195, 0x6200, 0x3401, + 0x0000, 0x03ce, 0x2803, 0xb391, 0xb88a, 0x0024, 0x36f3, 0xd80e, 0x36f1, + 0x980d, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0xb880, 0xb810, 0x0006, 0x9fd0, 0x3e10, 0x8001, 0x4182, + 0x3811, 0x0006, 0xd311, 0x2803, 0xbf45, 0x0006, 0x8a10, 0x0000, 0x0200, + 0xbc82, 0xa000, 0x3910, 0x0024, 0x2903, 0xb080, 0x39f0, 0x4024, 0x0006, + 0x9f90, 0x0006, 0x9f51, 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, 0x0024, + 0x0000, 0x0024, 0x2903, 0xc445, 0x0003, 0xc048, 0x36f4, 0x4024, 0x36f0, + 0x9810, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, + 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x290a, 0xd900, 0x3605, 0x0024, 0x2910, 0x0180, + 0x3613, 0x0024, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x0006, + 0x0002, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x0006, 0x9f90, + 0x3e04, 0xb813, 0x3009, 0x0012, 0x3213, 0x0024, 0xf400, 0x4480, 0x6026, + 0x0024, 0x0000, 0x0024, 0x2803, 0xccd5, 0x0000, 0x0024, 0x0000, 0x0012, + 0xf400, 0x4480, 0x0006, 0x9f50, 0x3009, 0x0002, 0x6026, 0x0024, 0x0000, + 0x0024, 0x2903, 0xc445, 0x0003, 0xccc8, 0x0006, 0x9f93, 0x3201, 0x0c11, + 0xb58a, 0x0406, 0x0006, 0x8a11, 0x468e, 0x8400, 0xb68c, 0x9813, 0xcfee, + 0x1bd2, 0x0000, 0x0804, 0xaf0e, 0x9811, 0x4f86, 0x1bd0, 0x0000, 0x0021, + 0x6418, 0x9807, 0x6848, 0x1bc6, 0xad46, 0x9805, 0xf400, 0x4080, 0x36f1, + 0x0024, 0x36f0, 0x9803, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, + 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, + 0x3e10, 0xb803, 0x3e11, 0x3805, 0x2803, 0xdb00, 0x3e04, 0x3811, 0x0000, + 0x0401, 0x2903, 0x9bc0, 0x3613, 0x0024, 0x0000, 0x0080, 0xb882, 0x130c, + 0xf400, 0x4510, 0x3010, 0x910c, 0x30f0, 0xc024, 0x6dc2, 0x0024, 0x3810, + 0x0024, 0x38f0, 0x4024, 0x0000, 0x0201, 0x3100, 0x0024, 0xb010, 0x0024, + 0x0000, 0x0024, 0x2803, 0xde55, 0x0000, 0x0024, 0x6894, 0x130c, 0xb886, + 0x1040, 0x3430, 0x4024, 0x6dca, 0x0024, 0x0030, 0x0011, 0x2803, 0xd6d1, + 0x0000, 0x0024, 0xbcd2, 0x0024, 0x0000, 0x0201, 0x2803, 0xde45, 0x0000, + 0x0024, 0x2903, 0x9bc0, 0x3613, 0x0024, 0x36f4, 0x1811, 0x36f1, 0x1805, + 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, + 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb815, + 0x0000, 0x800a, 0x3e14, 0x7813, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, + 0xb807, 0x3e13, 0xf80e, 0x6812, 0x0024, 0x3e03, 0x7810, 0x0fff, 0xffd3, + 0x0000, 0x0091, 0xbd86, 0x9850, 0x3e10, 0x3804, 0x3e00, 0x7812, 0xbe8a, + 0x8bcc, 0x409e, 0x8086, 0x2403, 0xe587, 0xfe49, 0x2821, 0x526a, 0x8801, + 0x5c87, 0x280e, 0x4eba, 0x9812, 0x4286, 0x40e1, 0xb284, 0x1bc1, 0x4de6, + 0x0024, 0xad17, 0x2627, 0x4fde, 0x9804, 0x4498, 0x1bc0, 0x0000, 0x0024, + 0x2803, 0xe395, 0x3a11, 0xa807, 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f4, 0x5813, 0x2000, 0x0000, + 0x36f2, 0x9815, 0x3613, 0x0024, 0x3e12, 0xb815, 0x0000, 0x800a, 0x3e10, + 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e13, 0xf80e, 0x6812, 0x0024, + 0x3e03, 0x7810, 0x3009, 0x1850, 0x3e10, 0x3804, 0x3e10, 0x7812, 0x32f3, + 0x0024, 0xbd86, 0x0024, 0x4091, 0xe2e3, 0x3009, 0x0046, 0x2403, 0xf100, + 0x3009, 0x0047, 0x32f0, 0x0801, 0xfe1f, 0x6465, 0x5e8a, 0x0024, 0x44ba, + 0x0024, 0xfee2, 0x0024, 0x5d8a, 0x1800, 0x4482, 0x4160, 0x48ba, 0x8046, + 0x4dc6, 0x1822, 0x4de6, 0x8047, 0x36f3, 0x0024, 0x36f0, 0x5812, 0xad17, + 0x2627, 0x4fde, 0x9804, 0x4498, 0x1bc0, 0x0000, 0x0024, 0x2803, 0xec95, + 0x3a11, 0xa807, 0x36f3, 0x4024, 0x36f3, 0xd80e, 0x36f1, 0x9807, 0x36f1, + 0x1805, 0x36f0, 0x9803, 0x2000, 0x0000, 0x36f2, 0x9815, 0xb386, 0x40d7, + 0x4284, 0x184c, 0x0000, 0x05c0, 0x2803, 0xf695, 0xf5d8, 0x3804, 0x0000, + 0x0984, 0x6400, 0xb84a, 0x3e13, 0xf80d, 0xa204, 0x380e, 0x0000, 0x800a, + 0x0000, 0x00ce, 0x2403, 0xf9ce, 0xffa4, 0x0024, 0x48b6, 0x0024, 0x0000, + 0x0024, 0x2803, 0xf9c4, 0x4000, 0x40c2, 0x4224, 0x0024, 0x6090, 0x0024, + 0xffa4, 0x0024, 0x0fff, 0xfe83, 0xfe86, 0x1bce, 0x36f3, 0xd80d, 0x48b6, + 0x0024, 0x0fff, 0xff03, 0xa230, 0x45c3, 0x2000, 0x0000, 0x36f1, 0x180a, + 0x4080, 0x184c, 0x3e13, 0x780f, 0x2803, 0xfe05, 0x4090, 0xb80e, 0x2403, + 0xfd80, 0x3e04, 0x0440, 0x3810, 0x0440, 0x3604, 0x0024, 0x3009, 0x1bce, + 0x3603, 0x5bcf, 0x2000, 0x0000, 0x0000, 0x0024, 0x0007, 0x0001, /*copy 1*/ + 0x802e, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x6280, 0x0007, 0x0001, /*copy 1*/ + 0x8030, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x1440, 0x0007, 0x0001, /*copy 1*/ + 0x8028, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x3c4e, 0x0007, 0x0001, /*copy 1*/ + 0x8032, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x59c0, 0x0007, 0x0001, /*copy 1*/ + 0x3580, 0x0006, 0x8038, 0x0000, /*Rle(56)*/ + 0x0007, 0x0001, /*copy 1*/ + 0xfab3, 0x0006, 0x01a4, /*copy 420*/ + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0xffff, 0xfffe, 0xfffb, 0xfff9, + 0xfff5, 0xfff2, 0xffed, 0xffe8, 0xffe3, 0xffde, 0xffd8, 0xffd3, 0xffce, + 0xffca, 0xffc7, 0xffc4, 0xffc4, 0xffc5, 0xffc7, 0xffcc, 0xffd3, 0xffdc, + 0xffe6, 0xfff3, 0x0001, 0x0010, 0x001f, 0x002f, 0x003f, 0x004e, 0x005b, + 0x0066, 0x006f, 0x0074, 0x0075, 0x0072, 0x006b, 0x005f, 0x004f, 0x003c, + 0x0024, 0x0009, 0xffed, 0xffcf, 0xffb0, 0xff93, 0xff77, 0xff5f, 0xff4c, + 0xff3d, 0xff35, 0xff34, 0xff3b, 0xff4a, 0xff60, 0xff7e, 0xffa2, 0xffcd, + 0xfffc, 0x002e, 0x0061, 0x0094, 0x00c4, 0x00f0, 0x0114, 0x0131, 0x0144, + 0x014b, 0x0146, 0x0134, 0x0116, 0x00eb, 0x00b5, 0x0075, 0x002c, 0xffde, + 0xff8e, 0xff3d, 0xfeef, 0xfea8, 0xfe6a, 0xfe39, 0xfe16, 0xfe05, 0xfe06, + 0xfe1b, 0xfe43, 0xfe7f, 0xfecd, 0xff2a, 0xff95, 0x0009, 0x0082, 0x00fd, + 0x0173, 0x01e1, 0x0242, 0x0292, 0x02cc, 0x02ec, 0x02f2, 0x02da, 0x02a5, + 0x0253, 0x01e7, 0x0162, 0x00c9, 0x0021, 0xff70, 0xfebc, 0xfe0c, 0xfd68, + 0xfcd5, 0xfc5b, 0xfc00, 0xfbc9, 0xfbb8, 0xfbd2, 0xfc16, 0xfc85, 0xfd1b, + 0xfdd6, 0xfeae, 0xff9e, 0x009c, 0x01a0, 0x02a1, 0x0392, 0x046c, 0x0523, + 0x05b0, 0x060a, 0x062c, 0x0613, 0x05bb, 0x0526, 0x0456, 0x0351, 0x021f, + 0x00c9, 0xff5a, 0xfde1, 0xfc6a, 0xfb05, 0xf9c0, 0xf8aa, 0xf7d0, 0xf73d, + 0xf6fa, 0xf70f, 0xf77e, 0xf848, 0xf96b, 0xfadf, 0xfc9a, 0xfe8f, 0x00ad, + 0x02e3, 0x051a, 0x073f, 0x0939, 0x0af4, 0x0c5a, 0x0d59, 0x0de1, 0x0de5, + 0x0d5c, 0x0c44, 0x0a9e, 0x0870, 0x05c7, 0x02b4, 0xff4e, 0xfbaf, 0xf7f8, + 0xf449, 0xf0c7, 0xed98, 0xeae0, 0xe8c4, 0xe765, 0xe6e3, 0xe756, 0xe8d2, + 0xeb67, 0xef19, 0xf3e9, 0xf9cd, 0x00b5, 0x088a, 0x112b, 0x1a72, 0x2435, + 0x2e42, 0x3866, 0x426b, 0x4c1b, 0x553e, 0x5da2, 0x6516, 0x6b6f, 0x7087, + 0x7441, 0x7686, 0x774a, 0x7686, 0x7441, 0x7087, 0x6b6f, 0x6516, 0x5da2, + 0x553e, 0x4c1b, 0x426b, 0x3866, 0x2e42, 0x2435, 0x1a72, 0x112b, 0x088a, + 0x00b5, 0xf9cd, 0xf3e9, 0xef19, 0xeb67, 0xe8d2, 0xe756, 0xe6e3, 0xe765, + 0xe8c4, 0xeae0, 0xed98, 0xf0c7, 0xf449, 0xf7f8, 0xfbaf, 0xff4e, 0x02b4, + 0x05c7, 0x0870, 0x0a9e, 0x0c44, 0x0d5c, 0x0de5, 0x0de1, 0x0d59, 0x0c5a, + 0x0af4, 0x0939, 0x073f, 0x051a, 0x02e3, 0x00ad, 0xfe8f, 0xfc9a, 0xfadf, + 0xf96b, 0xf848, 0xf77e, 0xf70f, 0xf6fa, 0xf73d, 0xf7d0, 0xf8aa, 0xf9c0, + 0xfb05, 0xfc6a, 0xfde1, 0xff5a, 0x00c9, 0x021f, 0x0351, 0x0456, 0x0526, + 0x05bb, 0x0613, 0x062c, 0x060a, 0x05b0, 0x0523, 0x046c, 0x0392, 0x02a1, + 0x01a0, 0x009c, 0xff9e, 0xfeae, 0xfdd6, 0xfd1b, 0xfc85, 0xfc16, 0xfbd2, + 0xfbb8, 0xfbc9, 0xfc00, 0xfc5b, 0xfcd5, 0xfd68, 0xfe0c, 0xfebc, 0xff70, + 0x0021, 0x00c9, 0x0162, 0x01e7, 0x0253, 0x02a5, 0x02da, 0x02f2, 0x02ec, + 0x02cc, 0x0292, 0x0242, 0x01e1, 0x0173, 0x00fd, 0x0082, 0x0009, 0xff95, + 0xff2a, 0xfecd, 0xfe7f, 0xfe43, 0xfe1b, 0xfe06, 0xfe05, 0xfe16, 0xfe39, + 0xfe6a, 0xfea8, 0xfeef, 0xff3d, 0xff8e, 0xffde, 0x002c, 0x0075, 0x00b5, + 0x00eb, 0x0116, 0x0134, 0x0146, 0x014b, 0x0144, 0x0131, 0x0114, 0x00f0, + 0x00c4, 0x0094, 0x0061, 0x002e, 0xfffc, 0xffcd, 0xffa2, 0xff7e, 0xff60, + 0xff4a, 0xff3b, 0xff34, 0xff35, 0xff3d, 0xff4c, 0xff5f, 0xff77, 0xff93, + 0xffb0, 0xffcf, 0xffed, 0x0009, 0x0024, 0x003c, 0x004f, 0x005f, 0x006b, + 0x0072, 0x0075, 0x0074, 0x006f, 0x0066, 0x005b, 0x004e, 0x003f, 0x002f, + 0x001f, 0x0010, 0x0001, 0xfff3, 0xffe6, 0xffdc, 0xffd3, 0xffcc, 0xffc7, + 0xffc5, 0xffc4, 0xffc4, 0xffc7, 0xffca, 0xffce, 0xffd3, 0xffd8, 0xffde, + 0xffe3, 0xffe8, 0xffed, 0xfff2, 0xfff5, 0xfff9, 0xfffb, 0xfffe, 0xffff, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0007, 0x0001, /*copy 1*/ + 0x180b, 0x0006, 0x000b, /*copy 11*/ + 0x000f, 0x0010, 0x001c, 0xfab3, 0x3580, 0x8037, 0xa037, 0x0001, 0x0000, + 0x3580, 0x01a4, 0x0007, 0x0001, /*copy 1*/ + 0x181a, 0x0006, 0x0002, /*copy 2*/ + 0x08b4, 0x08d2, 0x0006, 0x8006, 0x091a, /*Rle(6)*/ + 0x0006, 0x0025, /*copy 37*/ + 0x08ef, 0x08ef, 0x08ef, 0x08ef, 0x08ef, 0x0b11, 0x0af5, 0x0af9, 0x0afd, + 0x0b01, 0x0b05, 0x0b09, 0x0b0d, 0x0b40, 0x0b44, 0x0b47, 0x0b47, 0x0b47, + 0x0b47, 0x0b4f, 0x0b62, 0x0c2d, 0x0b99, 0x0b9e, 0x0ba4, 0x0baa, 0x0baf, + 0x0bb4, 0x0bb9, 0x0bbe, 0x0bc3, 0x0bc8, 0x0bcd, 0x0bd2, 0x0beb, 0x0c0a, + 0x0c29, 0x0007, 0x0001, /*copy 1*/ + 0x5800, 0x0006, 0x0001, /*copy 1*/ + 0x0001, 0x0006, 0x8007, 0x0000, /*Rle(7)*/ + 0x0006, 0x0018, /*copy 24*/ + 0x0002, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, + 0x0000, 0xfffd, 0xffff, 0x0001, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, + 0xfffa, 0xffff, 0x0004, 0x0000, 0xffff, 0xffff, 0x000a, 0x0001, /*copy 1*/ + 0x0050, +#define PLUGIN_SIZE 8588 +#ifndef SKIP_PLUGIN_VARNAME +}; +#endif diff --git a/targets/esp32/components/VS1053/include/patches_latm.h b/targets/esp32/components/VS1053/include/patches_latm.h new file mode 100644 index 00000000..115525f1 --- /dev/null +++ b/targets/esp32/components/VS1053/include/patches_latm.h @@ -0,0 +1,644 @@ + +#ifndef SKIP_PLUGIN_VARNAME +const unsigned short PLUGIN[] = { + /* Compressed plugin */ +#endif + 0x0007, 0x0001, /*copy 1*/ + 0x8050, 0x0006, 0x001e, /*copy 30*/ + 0x2a00, 0xc000, 0x3e12, 0xb817, 0x3e14, 0xf812, 0x3e01, 0xb811, 0x0007, + 0x9717, 0x0020, 0xffd2, 0x0030, 0x11d1, 0x3111, 0x8024, 0x3704, 0xc024, + 0x3b81, 0x8024, 0x3101, 0x8024, 0x3b81, 0x8024, 0x3f04, 0xc024, 0x2808, + 0x4800, 0x36f1, 0x9811, 0x0007, 0x0001, /*copy 1*/ + 0x8060, 0x0006, 0x0536, /*copy 1334*/ + 0xf400, 0x4095, 0x0000, 0x02c2, 0x6124, 0x0024, 0x0000, 0x0024, 0x2800, + 0x1ac5, 0x4192, 0x4542, 0x0000, 0x0041, 0x2000, 0x0015, 0x0030, 0x0317, + 0x2000, 0x0000, 0x3f00, 0x4024, 0x2000, 0x0000, 0x0000, 0x0000, 0x3e12, + 0x3800, 0x3e00, 0xb804, 0x0030, 0x0015, 0x0007, 0x8257, 0x3700, 0x984c, + 0xf224, 0x1444, 0xf224, 0x0024, 0x0008, 0x0002, 0x2910, 0x0181, 0x0000, + 0x1bc8, 0xb428, 0x1402, 0x0000, 0x8004, 0x2910, 0x0195, 0x0000, 0x1bc8, + 0xb428, 0x0024, 0x0006, 0x0095, 0x2800, 0x2945, 0x3e13, 0x780e, 0x3e11, + 0x7803, 0x3e13, 0xf806, 0x3e11, 0xf801, 0x3510, 0xb808, 0x003f, 0xe004, + 0xfec4, 0x3800, 0x48be, 0x17c3, 0xfec6, 0x41c2, 0x48be, 0x4497, 0x4090, + 0x1c46, 0xf06c, 0x0024, 0x2400, 0x2580, 0x6090, 0x41c3, 0x6628, 0x1c47, + 0x0000, 0x0024, 0x2800, 0x2449, 0xf07e, 0x0024, 0xf400, 0x4182, 0x673a, + 0x1c46, 0x0000, 0x0024, 0x2800, 0x2589, 0xf06c, 0x0024, 0xf400, 0x41c3, + 0x0000, 0x0024, 0x4224, 0x3442, 0x2900, 0xb7c0, 0x4336, 0x37c3, 0x0000, + 0x1805, 0x2900, 0xb7c0, 0x4508, 0x40c2, 0x450a, 0x9808, 0x0000, 0x0207, + 0xa478, 0x1bc0, 0xc45a, 0x1807, 0x0030, 0x03d5, 0x3d01, 0x5bc1, 0x36f3, + 0xd806, 0x3601, 0x5803, 0x36f3, 0x0024, 0x36f3, 0x580e, 0x0007, 0x8257, + 0x0000, 0x6004, 0x3730, 0x8024, 0xb244, 0x1c04, 0xd428, 0x3c02, 0x0006, + 0xc717, 0x2800, 0x2d05, 0x4284, 0x0024, 0x3613, 0x3c02, 0x0006, 0xc357, + 0x2901, 0x6480, 0x3e11, 0x5c05, 0x4284, 0x1bc5, 0x0000, 0x0024, 0x2800, + 0x3045, 0x0000, 0x0024, 0x0030, 0x0117, 0x3f00, 0x0024, 0x3613, 0x0024, + 0x3e10, 0x3813, 0x3e14, 0x8024, 0x3e04, 0x8024, 0x2900, 0x4900, 0x0006, + 0x02d3, 0x36e3, 0x0024, 0x3009, 0x1bd3, 0x0007, 0x8257, 0x3700, 0x8024, + 0xf224, 0x0024, 0x0000, 0x0024, 0x2800, 0x3251, 0x3600, 0x9844, 0x2900, + 0x3800, 0x0000, 0x32c8, 0x2911, 0xf140, 0x0000, 0x0024, 0x0030, 0x0057, + 0x3700, 0x0024, 0xf200, 0x4595, 0x0fff, 0xfe02, 0xa024, 0x164c, 0x8000, + 0x17cc, 0x3f00, 0x0024, 0x3500, 0x0024, 0x0021, 0x6d82, 0xd024, 0x44c0, + 0x0006, 0xa402, 0x2800, 0x3715, 0xd024, 0x0024, 0x0000, 0x0000, 0x2800, + 0x3715, 0x000b, 0x6d57, 0x3009, 0x3c00, 0x36f0, 0x8024, 0x36f2, 0x1800, + 0x2000, 0x0000, 0x0000, 0x0024, 0x3e14, 0x7810, 0x3e13, 0xb80d, 0x3e13, + 0xf80a, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0xf801, + 0x3e15, 0x3815, 0x0001, 0x000a, 0x0006, 0xc4d7, 0xbf8e, 0x9c42, 0x3e01, + 0x9c03, 0x0006, 0xa017, 0x0023, 0xffd1, 0x0007, 0x8250, 0x0fff, 0xfd85, + 0x3001, 0x0024, 0xa45a, 0x4494, 0x0000, 0x0093, 0x2800, 0x3e51, 0xf25a, + 0x104c, 0x34f3, 0x0024, 0x2800, 0x3e51, 0x0000, 0x0024, 0x3413, 0x084c, + 0x0000, 0x0095, 0x3281, 0xf806, 0x4091, 0x4d64, 0x2400, 0x4080, 0x4efa, + 0x9c10, 0xf1eb, 0x6061, 0xfe55, 0x2f66, 0x5653, 0x4d64, 0x48b2, 0xa201, + 0x4efa, 0xa201, 0x36f3, 0x3c10, 0x36f5, 0x1815, 0x36f4, 0xd801, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0xd80a, 0x36f3, 0x980d, + 0x2000, 0x0000, 0x36f4, 0x5810, 0x36f3, 0x0024, 0x3009, 0x3848, 0x3e14, + 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, 0x2915, 0x94c0, + 0x0001, 0xcc11, 0x36f0, 0x0024, 0x2927, 0x9e40, 0x3604, 0x1811, 0x3613, + 0x0024, 0x3e14, 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, + 0x2915, 0x94c0, 0x0001, 0xcc11, 0x36f0, 0x0024, 0x36f4, 0x1811, 0x3009, + 0x1808, 0x2000, 0x0000, 0x0000, 0x190d, 0x3613, 0x0024, 0x3e22, 0xb815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e13, 0x7801, 0x3e10, + 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x3e14, 0xb813, + 0x3e03, 0xf80e, 0xb488, 0x44d5, 0x3543, 0x134c, 0x34e5, 0xc024, 0x3524, + 0x8024, 0x35a4, 0xc024, 0x3710, 0x8a0c, 0x3540, 0x4a0c, 0x3d44, 0x8024, + 0x3a10, 0x8024, 0x3590, 0x0024, 0x4010, 0x15c1, 0x6010, 0x3400, 0x3710, + 0x8024, 0x2800, 0x54c4, 0x3af0, 0x8024, 0x3df0, 0x0024, 0x3591, 0x4024, + 0x3530, 0x4024, 0x4192, 0x4050, 0x6100, 0x1482, 0x4020, 0x1753, 0xbf8e, + 0x1582, 0x4294, 0x4011, 0xbd86, 0x408e, 0x2400, 0x52ce, 0xfe6d, 0x2819, + 0x520e, 0x0a00, 0x5207, 0x2819, 0x4fbe, 0x0024, 0xad56, 0x904c, 0xaf5e, + 0x1010, 0xf7d4, 0x0024, 0xf7fc, 0x2042, 0x6498, 0x2046, 0x3cf4, 0x0024, + 0x3400, 0x170c, 0x4090, 0x1492, 0x35a4, 0xc024, 0x2800, 0x4d55, 0x3c00, + 0x0024, 0x4480, 0x914c, 0x36f3, 0xd80e, 0x36f4, 0x9813, 0x36f4, 0x1811, + 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0x5801, 0x3405, + 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x2814, 0x9c91, + 0x0000, 0x004d, 0x2814, 0x9940, 0x003f, 0x0013, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3655, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb810, 0x3e13, + 0xf80e, 0x3e03, 0x534c, 0x3450, 0x4024, 0x6814, 0x0024, 0x0000, 0x0024, + 0x2800, 0x73d8, 0x4192, 0x0024, 0x2400, 0x7381, 0x0000, 0x0024, 0xf400, + 0x4450, 0x2938, 0x1880, 0x3613, 0x0024, 0x3c10, 0x050c, 0x3c10, 0x4024, + 0x3c90, 0x8024, 0x34f3, 0x0024, 0x3464, 0x0024, 0x3011, 0x0c40, 0x3011, + 0x4c41, 0x2915, 0x9900, 0x3011, 0x8f82, 0x3411, 0x2c40, 0x3411, 0x6c41, + 0x2915, 0xa580, 0x34e1, 0xaf82, 0x3009, 0x3040, 0x4c8a, 0x0040, 0x3010, + 0x7041, 0x2800, 0x6614, 0x3010, 0xb382, 0x3411, 0x0024, 0x3411, 0x6c44, + 0x34e1, 0xac45, 0xbe8a, 0xaf86, 0x0fe0, 0x0006, 0x3009, 0x3044, 0x3009, + 0x3045, 0x3009, 0x3386, 0x3411, 0x0024, 0x3411, 0x4ccc, 0x2915, 0x9900, + 0x34e1, 0x984c, 0x3e10, 0x7800, 0x3009, 0x3802, 0x3011, 0x0c40, 0x3011, + 0x4c41, 0x2915, 0x9900, 0x30e1, 0x8f82, 0x3009, 0x1bc6, 0x2915, 0xa940, + 0x36f1, 0x5804, 0x3011, 0x2c40, 0x3011, 0x6c41, 0x30b1, 0xac42, 0x3009, + 0x0c40, 0x3009, 0x0c41, 0x2915, 0x9900, 0x3613, 0x0f82, 0x3e10, 0x7800, + 0x3009, 0x3802, 0x3010, 0x1044, 0x3010, 0x5045, 0x2915, 0x9900, 0x3010, + 0x9386, 0x3009, 0x1bc6, 0x2915, 0xa940, 0x36f1, 0x5804, 0xf1ca, 0xac40, + 0x4ce2, 0xac41, 0x3009, 0x2ec2, 0x2800, 0x6ed2, 0x629c, 0x0024, 0xf1c2, + 0x4182, 0x3c10, 0x0c44, 0x3c10, 0x4c45, 0x2915, 0x4780, 0x3ce0, 0x8f86, + 0x4080, 0x0024, 0x0000, 0x0024, 0x2800, 0x7395, 0x0020, 0x0000, 0x3411, + 0x0c40, 0x3411, 0x4c41, 0x2915, 0xb780, 0x34e1, 0x8f82, 0x0000, 0x03c3, + 0x4234, 0x0024, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2915, 0x4355, 0x0000, + 0x7388, 0x0000, 0x0000, 0x3a10, 0x0d8c, 0x36f3, 0x538c, 0x36f3, 0xd80e, + 0x36f1, 0x9810, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3645, + 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, + 0x3e11, 0xb810, 0x3e13, 0xf80e, 0x3e03, 0x534c, 0x3440, 0x4024, 0x4192, + 0x0024, 0x2400, 0x8f81, 0x0000, 0x0024, 0xb68c, 0x4450, 0x2938, 0x1880, + 0x3613, 0x050c, 0x3c10, 0x0c40, 0x3c10, 0x4c41, 0x3ce0, 0x8f82, 0x003c, + 0x2584, 0x2915, 0x9900, 0x0018, 0x8245, 0x3411, 0x2c40, 0x3411, 0x6c41, + 0x2915, 0xa580, 0x34e1, 0xac42, 0x4c8a, 0xb040, 0x3009, 0x3041, 0x2800, + 0x8094, 0x3009, 0x3382, 0x3411, 0x0f4c, 0x3411, 0x6c44, 0x34e1, 0xac45, + 0xbe8a, 0xac46, 0x499c, 0xb044, 0xf38c, 0xb045, 0x3009, 0x3386, 0x3009, + 0x0c40, 0x3009, 0x0c41, 0xf1ca, 0x8f82, 0x4ce2, 0x1044, 0x3411, 0x4024, + 0x2800, 0x82d2, 0x4294, 0x1386, 0x6294, 0x0024, 0xf1c2, 0x0024, 0x4e8a, + 0x4195, 0x35e3, 0x0024, 0x2915, 0xa955, 0xf400, 0x4546, 0x3009, 0x2c40, + 0x3009, 0x2c41, 0x3009, 0x2c42, 0x3009, 0x0c40, 0x3009, 0x0c41, 0xf1ca, + 0x8f82, 0x4ce2, 0x9044, 0x3009, 0x1045, 0x2800, 0x8745, 0x3009, 0x1386, + 0x2800, 0x8752, 0x4294, 0x0024, 0x6294, 0x0024, 0xf1c2, 0x0024, 0x4e8a, + 0x4195, 0x35e3, 0x0024, 0x2915, 0xa955, 0xf400, 0x4546, 0xf1ca, 0xac40, + 0x4ce2, 0xac41, 0x3009, 0x2ec2, 0x2800, 0x89d2, 0x629c, 0x0024, 0xf1c2, + 0x4182, 0x3c20, 0x0c84, 0x3cf0, 0x8fc6, 0x6264, 0x4017, 0x3cf0, 0x4fc5, + 0x2800, 0x8f88, 0x0020, 0x0000, 0x2800, 0x8cd9, 0xf400, 0x45c0, 0x6cea, + 0x0024, 0x0000, 0x0024, 0x2800, 0x8f89, 0x0020, 0x0000, 0x3411, 0x0c40, + 0x3411, 0x4c41, 0x2915, 0xb780, 0x34e1, 0x8f82, 0x0000, 0x03c3, 0x4234, + 0x0024, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2915, 0x4355, 0x0000, 0x8f88, + 0x0000, 0x0000, 0x3a10, 0x0d8c, 0x36f3, 0x53cc, 0x36f3, 0xd80e, 0x36f1, + 0x9810, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0xf400, + 0x4595, 0x35e3, 0x3840, 0x3e13, 0xf80e, 0x3e13, 0x7808, 0x3510, 0x0024, + 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e00, + 0x0024, 0x0001, 0xb0ce, 0x002b, 0xb30f, 0x292d, 0xa940, 0x0000, 0x004d, + 0x36d3, 0x0024, 0x36f3, 0x5808, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x3009, + 0x1800, 0xf400, 0x4595, 0x35f3, 0x3840, 0x3e13, 0xf80e, 0x3e13, 0x7808, + 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e00, 0x0024, 0x0000, + 0x9b8e, 0x0028, 0x088f, 0x2927, 0xff80, 0x0000, 0x008d, 0x36e3, 0x0024, + 0x36f3, 0x5808, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x3009, 0x1800, 0x0028, + 0x2b0f, 0x0000, 0xa10e, 0x2828, 0x0b15, 0x0007, 0x2605, 0x3613, 0x0001, + 0x3e14, 0x3811, 0x0001, 0x0011, 0x0001, 0xcc10, 0x2915, 0x94c0, 0x0000, + 0x4000, 0x3e10, 0x534c, 0x3430, 0xc024, 0x3e10, 0xc024, 0x2927, 0xc4c0, + 0x3e01, 0x0024, 0x36d3, 0x0024, 0x0001, 0x0011, 0x0001, 0xcc10, 0x2915, + 0x94c0, 0x0000, 0x4000, 0x2828, 0x0b00, 0x36f4, 0x1811, 0x3e00, 0x0024, + 0x2800, 0xa500, 0x0028, 0x2bc8, 0x3605, 0x7840, 0x3e13, 0x780e, 0x3e13, + 0xf808, 0x3e05, 0x4024, 0x0000, 0x434e, 0x0027, 0x9e0f, 0x2922, 0xa6c0, + 0x0000, 0x190d, 0x36f3, 0x0024, 0x36f3, 0xd808, 0x36f3, 0x580e, 0x2000, + 0x0000, 0x3009, 0x1800, 0xf400, 0x4595, 0x35d3, 0x3840, 0x3e13, 0xf80e, + 0x3e13, 0x7808, 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e10, + 0x0024, 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e00, 0x0024, + 0x0000, 0xaa4e, 0x0025, 0xf54f, 0x2925, 0xe580, 0x0000, 0x004d, 0x36c3, + 0x0024, 0x36f3, 0x5808, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x3009, 0x1800, + 0x3433, 0x0000, 0x6890, 0x3040, 0x3cc0, 0xa000, 0x0008, 0x6201, 0x000d, + 0x3500, 0x3613, 0x110c, 0x3e10, 0x0024, 0x3e10, 0x4024, 0x34c0, 0x8024, + 0x2900, 0x9280, 0x3e00, 0x8024, 0x0026, 0x0a4f, 0x0000, 0xae0e, 0x2825, + 0xf880, 0x0000, 0x07cd, 0x0000, 0x0801, 0x6012, 0x0024, 0x0000, 0x0024, + 0x2826, 0x0a85, 0x0000, 0x0024, 0x2800, 0xab00, 0x0000, 0x0024, 0x3605, + 0x7840, 0x3e13, 0x780e, 0x3e13, 0xf808, 0x3e05, 0x4024, 0x0000, 0xb30e, + 0x0022, 0xf54f, 0x2922, 0xda80, 0x0000, 0x190d, 0x36f3, 0x0024, 0x36f3, + 0xd808, 0x36f3, 0x580e, 0x2000, 0x0000, 0x3009, 0x1800, 0x3e00, 0x0024, + 0x2800, 0x9740, 0x0022, 0xf608, 0x3605, 0x7840, 0x3e13, 0x780e, 0x3e13, + 0xf808, 0x3e05, 0x4024, 0x0000, 0xb70e, 0x0022, 0xa1cf, 0x2922, 0x9980, + 0x0000, 0x190d, 0x36f3, 0x0024, 0x36f3, 0xd808, 0x36f3, 0x580e, 0x2000, + 0x0000, 0x3009, 0x1800, 0x3009, 0x3400, 0x2800, 0xafc0, 0x0022, 0xa288, + 0xb386, 0x40d7, 0x4284, 0x184c, 0x0000, 0x05c0, 0x2800, 0xb955, 0xf5d8, + 0x3804, 0x0000, 0x0984, 0x6400, 0xb84a, 0x3e13, 0xf80d, 0xa204, 0x380e, + 0x0000, 0x800a, 0x0000, 0x00ce, 0x2400, 0xbc8e, 0xffa4, 0x0024, 0x48b6, + 0x0024, 0x0000, 0x0024, 0x2800, 0xbc84, 0x4000, 0x40c2, 0x4224, 0x0024, + 0x6090, 0x0024, 0xffa4, 0x0024, 0x0fff, 0xfe83, 0xfe86, 0x1bce, 0x36f3, + 0xd80d, 0x48b6, 0x0024, 0x0fff, 0xff03, 0xa230, 0x45c3, 0x2000, 0x0000, + 0x36f1, 0x180a, 0x0007, 0x0001, /*copy 1*/ + 0x8300, 0x0006, 0x0e92, /*copy 3730*/ + 0x0030, 0x0055, 0xb080, 0x1402, 0x0fdf, 0xffc1, 0x0007, 0x9257, 0xb212, + 0x3c00, 0x3d00, 0x4024, 0x0006, 0x0097, 0x3f10, 0x0024, 0x3f00, 0x0024, + 0x0030, 0x0297, 0x3f00, 0x0024, 0x0007, 0x9017, 0x3f00, 0x0024, 0x0007, + 0x81d7, 0x3f10, 0x0024, 0xc090, 0x3c00, 0x0006, 0x0297, 0xb080, 0x3c00, + 0x0000, 0x0401, 0x000a, 0x1055, 0x0006, 0x0017, 0x3f10, 0x3401, 0x000a, + 0x2795, 0x3f00, 0x3401, 0x0001, 0x6457, 0xf400, 0x55c0, 0x0000, 0x0817, + 0xb080, 0x57c0, 0x0014, 0x958f, 0x0000, 0x590e, 0x0030, 0x0017, 0x3700, + 0x0024, 0x0004, 0x0001, 0xb012, 0x0024, 0x0000, 0x004d, 0x280f, 0xe115, + 0x0006, 0x2016, 0x0006, 0x01d7, 0x3f00, 0x0024, 0x0000, 0x190d, 0x000f, + 0xf94f, 0x0000, 0xcd0e, 0x280f, 0xe100, 0x0006, 0x2016, 0x0000, 0x0080, + 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, + 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0007, 0x8a57, 0x3700, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0040, 0x2800, 0xced5, 0x0006, 0xa2d7, 0x3009, + 0x3c00, 0x0006, 0xa157, 0x3009, 0x1c00, 0x0006, 0x01d7, 0x0000, 0x190d, + 0x000a, 0x708f, 0x0000, 0xd7ce, 0x290b, 0x1a80, 0x3f00, 0x184c, 0x0030, + 0x0017, 0x4080, 0x1c01, 0x0000, 0x0200, 0x2800, 0xcb15, 0xb102, 0x0024, + 0x0000, 0xcd08, 0x2800, 0xcb15, 0x0000, 0xd3ce, 0x0011, 0x210f, 0x0000, + 0x190d, 0x280f, 0xcb00, 0x3613, 0x0024, 0x0006, 0xa115, 0x0006, 0x01d7, + 0x37f0, 0x1401, 0x6100, 0x1c01, 0x4012, 0x0024, 0x0000, 0x8000, 0x6010, + 0x0024, 0x34f3, 0x0400, 0x2800, 0xd698, 0x0000, 0x0024, 0x0000, 0x8001, + 0x6010, 0x3c01, 0x0000, 0x000d, 0x2811, 0x8259, 0x0000, 0x0024, 0x2a11, + 0x2100, 0x0030, 0x0257, 0x3700, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2800, 0xd9d5, 0x0006, 0x0197, 0x0006, 0xa115, 0x3f00, 0x3400, 0x003f, + 0xc000, 0xb600, 0x41c1, 0x0012, 0x5103, 0x000c, 0xc002, 0xdcd6, 0x0024, + 0x0019, 0xd4c2, 0x2802, 0x8345, 0x0001, 0x0988, 0x0013, 0xd9c3, 0x6fd6, + 0x0024, 0x0000, 0x190d, 0x2800, 0xdf95, 0x0014, 0x1b01, 0x0020, 0x480f, + 0x0000, 0xde4e, 0x0000, 0x190d, 0x2820, 0x41c0, 0x0001, 0x0988, 0x0039, + 0x324f, 0x0001, 0x384e, 0x2820, 0x4a18, 0xb882, 0x0024, 0x2a20, 0x48c0, + 0x003f, 0xfd00, 0xb700, 0x0024, 0x003f, 0xf901, 0x6010, 0x0024, 0x0000, + 0x0024, 0x280a, 0xc505, 0x0000, 0x190d, 0x2a00, 0xe180, 0x000a, 0x8c8f, + 0x0000, 0xe2ce, 0x000c, 0x0981, 0x280a, 0x71c0, 0x002c, 0x9d40, 0x000a, + 0x708f, 0x0000, 0xd7ce, 0x280a, 0xc0d5, 0x0012, 0x5182, 0x6fd6, 0x0024, + 0x003f, 0xfd81, 0x280a, 0x8e45, 0xb710, 0x0024, 0x003f, 0xf800, 0xb600, + 0x0024, 0x0015, 0xb801, 0x6012, 0x0024, 0x003f, 0xfd81, 0x2802, 0x4ec5, + 0x0001, 0x0a88, 0xb710, 0x0024, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, + 0x0101, 0x2801, 0x0055, 0xffd2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, + 0x0000, 0x190d, 0x2801, 0x0055, 0x0030, 0x0250, 0xb880, 0x104c, 0x3cf0, + 0x0024, 0x0010, 0x5500, 0xb880, 0x23c0, 0xb882, 0x2000, 0x0007, 0x8590, + 0x2914, 0xbec0, 0x0000, 0x0440, 0x0007, 0x8b50, 0xb880, 0x0024, 0x2920, + 0x0100, 0x3800, 0x0024, 0x2920, 0x0000, 0x0006, 0x8a91, 0x0000, 0x0800, + 0xb880, 0xa440, 0x003f, 0xfd81, 0xb710, 0xa7c0, 0x003f, 0xfc01, 0x6012, + 0x0024, 0x0000, 0x0101, 0x2801, 0x0995, 0x0000, 0x0024, 0xffe2, 0x0024, + 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, 0x0995, 0x0000, + 0x0024, 0x2912, 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, 0x0006, 0x8a90, + 0x2801, 0x0995, 0x0000, 0x01c2, 0xb886, 0x8040, 0x3613, 0x03c1, 0xbcd2, + 0x0024, 0x0030, 0x0011, 0x2800, 0xf615, 0x003f, 0xff42, 0xb886, 0x8040, + 0x3009, 0x03c1, 0x0000, 0x0020, 0xac22, 0x0024, 0x0000, 0x0102, 0x6cd2, + 0x0024, 0x3e10, 0x0024, 0x2909, 0x8c80, 0x3e00, 0x4024, 0x36f3, 0x0024, + 0x3e11, 0x8024, 0x3e01, 0xc024, 0x2901, 0x2e40, 0x0000, 0x0201, 0xf400, + 0x4512, 0x2900, 0x0c80, 0x3213, 0x1b8c, 0x3100, 0x0024, 0xb010, 0x0024, + 0x0000, 0x0024, 0x2801, 0x0995, 0x0000, 0x0024, 0x291a, 0x8a40, 0x0000, + 0x0100, 0x2920, 0x0200, 0x3633, 0x0024, 0x2920, 0x0280, 0x0000, 0x0401, + 0x408e, 0x0024, 0x2920, 0x0280, 0x0000, 0x0401, 0x003f, 0xfd81, 0xb710, + 0x4006, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, 0x0995, + 0x0000, 0x0024, 0xffe2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, + 0x0024, 0x2801, 0x0995, 0x0000, 0x0024, 0x2912, 0x2d80, 0x0000, 0x0780, + 0x4080, 0x0024, 0x0000, 0x01c2, 0x2800, 0xf205, 0x0006, 0x8a90, 0x2a01, + 0x0980, 0x2920, 0x0100, 0x0000, 0x0401, 0x0000, 0x0180, 0x2920, 0x0200, + 0x3613, 0x0024, 0x2920, 0x0280, 0x3613, 0x0024, 0x0000, 0x0401, 0x2920, + 0x0280, 0x4084, 0x984c, 0x0019, 0x9d01, 0x6212, 0x0024, 0x001e, 0x5c01, + 0x2801, 0x04d5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x06c5, 0x0000, + 0x0024, 0x001b, 0x5bc1, 0x6212, 0x0024, 0x001b, 0xdd81, 0x2801, 0x0a95, + 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x0a95, 0x0000, 0x0024, 0x0000, + 0x004d, 0x000a, 0xbf4f, 0x280a, 0xb880, 0x0001, 0x07ce, 0x0020, 0xfb4f, + 0x0000, 0x190d, 0x0001, 0x0ece, 0x2920, 0xf440, 0x3009, 0x2bc1, 0x291a, + 0x8a40, 0x36e3, 0x0024, 0x0000, 0x190d, 0x000a, 0x708f, 0x280a, 0xcac0, + 0x0000, 0xd7ce, 0x0030, 0x0017, 0x3700, 0x4024, 0x0000, 0x0200, 0xb102, + 0x0024, 0x0000, 0x00c0, 0x2801, 0x0dc5, 0x0005, 0x4f92, 0x2909, 0xf840, + 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, 0xa115, 0xb080, 0x0024, 0x3f00, + 0x3400, 0x0000, 0x190d, 0x000a, 0x708f, 0x280a, 0xc0c0, 0x0000, 0xd7ce, + 0x0000, 0x004d, 0x0020, 0xfe0f, 0x2820, 0xfb40, 0x0001, 0x0fce, 0x2801, + 0x1195, 0x3009, 0x1000, 0x6012, 0x93cc, 0x0000, 0x0024, 0x2801, 0x2c45, + 0x0000, 0x0024, 0x3413, 0x0024, 0x34b0, 0x0024, 0x4080, 0x0024, 0x0000, + 0x0200, 0x2801, 0x1495, 0xb882, 0x0024, 0x3453, 0x0024, 0x3009, 0x13c0, + 0x4080, 0x0024, 0x0000, 0x0200, 0x2801, 0x2c45, 0x0000, 0x0024, 0xb882, + 0x130c, 0x0000, 0x004d, 0x0021, 0x058f, 0x2821, 0x0340, 0x0001, 0x158e, + 0x2801, 0x25d5, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x25d5, 0x0000, + 0x0024, 0x34c3, 0x184c, 0x3e13, 0xb80f, 0xf400, 0x4500, 0x0026, 0x9dcf, + 0x0001, 0x198e, 0x0000, 0xfa0d, 0x2926, 0x8e80, 0x3e10, 0x110c, 0x36f3, + 0x0024, 0x2801, 0x25c0, 0x36f3, 0x980f, 0x001c, 0xdd00, 0x001c, 0xd901, + 0x6ec2, 0x0024, 0x001c, 0xdd00, 0x2801, 0x1c95, 0x0018, 0xdbc1, 0x3413, + 0x184c, 0xf400, 0x4500, 0x2926, 0xc640, 0x3e00, 0x13cc, 0x2801, 0x2380, + 0x36f3, 0x0024, 0x6ec2, 0x0024, 0x003f, 0xc000, 0x2801, 0x1f15, 0x002a, + 0x4001, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0xafc0, 0x3e00, 0x13cc, + 0x2801, 0x2380, 0x36f3, 0x0024, 0xb400, 0x0024, 0xd100, 0x0024, 0x0000, + 0x0024, 0x2801, 0x2385, 0x0000, 0x0024, 0x3613, 0x0024, 0x3e11, 0x4024, + 0x2926, 0x8540, 0x3e01, 0x0024, 0x4080, 0x1b8c, 0x0000, 0x0024, 0x2801, + 0x2385, 0x0000, 0x0024, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0x8e80, + 0x3e10, 0x13cc, 0x36f3, 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, 0x0000, + 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, 0x3110, 0x8024, 0x2826, 0xa8c4, + 0x31f0, 0xc024, 0x2a26, 0xad00, 0x34c3, 0x184c, 0x3410, 0x8024, 0x3430, + 0xc024, 0x0000, 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, 0x0000, 0x0024, + 0x2801, 0x2c54, 0x4d06, 0x0024, 0x0000, 0x0200, 0x2922, 0x1885, 0x0001, + 0x2ac8, 0x0000, 0x0200, 0x3e10, 0x8024, 0x2921, 0xca80, 0x3e00, 0xc024, + 0x291a, 0x8a40, 0x0000, 0x0024, 0x2922, 0x1880, 0x36f3, 0x0024, 0x0000, + 0x004d, 0x0021, 0x0ecf, 0x2821, 0x0bc0, 0x0001, 0x2bce, 0x2801, 0x0ec0, + 0x3c30, 0x4024, 0x0000, 0x190d, 0x0001, 0x2d4e, 0x2821, 0x0f80, 0x0021, + 0x420f, 0x0000, 0x190d, 0x3e00, 0x0024, 0x2801, 0xca80, 0x0021, 0x42c8, + 0x0020, 0xcd4f, 0x2820, 0xc780, 0x0001, 0x2f0e, 0x0006, 0xf017, 0x0000, + 0x0015, 0xb070, 0xbc15, 0x0001, 0x30ce, 0x0020, 0xdf0f, 0x2820, 0xcd80, + 0x0000, 0x190d, 0x3e00, 0x23c1, 0x2801, 0xca80, 0x0020, 0xdfc8, 0x3613, + 0x0024, 0x3e10, 0xb803, 0x3e14, 0x3811, 0x3e11, 0x3805, 0x3e00, 0x3801, + 0x0007, 0xc390, 0x0006, 0xa011, 0x3010, 0x0444, 0x3050, 0x4405, 0x6458, + 0x0302, 0xff94, 0x4081, 0x0003, 0xffc5, 0x48b6, 0x0024, 0xff82, 0x0024, + 0x42b2, 0x0042, 0xb458, 0x0003, 0x4cd6, 0x9801, 0xf248, 0x1bc0, 0xb58a, + 0x0024, 0x6de6, 0x1804, 0x0006, 0x0010, 0x3810, 0x9bc5, 0x3800, 0xc024, + 0x36f4, 0x1811, 0x36f0, 0x9803, 0x283e, 0x2d80, 0x0fff, 0xffc3, 0x2801, + 0x4600, 0x0000, 0x0024, 0x3413, 0x0024, 0x2801, 0x3a05, 0xf400, 0x4517, + 0x2801, 0x3e00, 0x6894, 0x13cc, 0x37b0, 0x184c, 0x6090, 0x1d51, 0x0000, + 0x0910, 0x3f00, 0x060c, 0x3100, 0x4024, 0x6016, 0xb812, 0x000c, 0x8012, + 0x2801, 0x3c91, 0xb884, 0x0024, 0x6894, 0x3002, 0x0000, 0x028d, 0x003a, + 0x5e0f, 0x0001, 0x4e0e, 0x2939, 0xb0c0, 0x3e10, 0x93cc, 0x4084, 0x9bd2, + 0x4282, 0x0024, 0x0000, 0x0040, 0x2801, 0x4005, 0x4292, 0x130c, 0x3443, + 0x0024, 0x2801, 0x4145, 0x000c, 0x8390, 0x2a01, 0x44c0, 0x3444, 0x0024, + 0x3073, 0x0024, 0xc090, 0x014c, 0x2801, 0x44c0, 0x3800, 0x0024, 0x000c, + 0x4113, 0xb880, 0x2380, 0x3304, 0x4024, 0x3800, 0x05cc, 0xcc92, 0x05cc, + 0x3910, 0x0024, 0x3910, 0x4024, 0x000c, 0x8110, 0x3910, 0x0024, 0x39f0, + 0x4024, 0x3810, 0x0024, 0x38d0, 0x4024, 0x3810, 0x0024, 0x38f0, 0x4024, + 0x34c3, 0x0024, 0x3444, 0x0024, 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, 0x4284, 0x0024, + 0x3613, 0x0024, 0x2801, 0x4805, 0x6898, 0xb804, 0x0000, 0x0084, 0x293b, + 0x1cc0, 0x3613, 0x0024, 0x000c, 0x8117, 0x3711, 0x0024, 0x37d1, 0x4024, + 0x4e8a, 0x0024, 0x0000, 0x0015, 0x2801, 0x4ac5, 0xce9a, 0x0024, 0x3f11, + 0x0024, 0x3f01, 0x4024, 0x000c, 0x8197, 0x408a, 0x9bc4, 0x3f15, 0x4024, + 0x2801, 0x4d05, 0x4284, 0x3c15, 0x6590, 0x0024, 0x0000, 0x0024, 0x2839, + 0x53d5, 0x4284, 0x0024, 0x0000, 0x0024, 0x2801, 0x38d8, 0x458a, 0x0024, + 0x2a39, 0x53c0, 0x003e, 0x2d4f, 0x283a, 0x5ed5, 0x0001, 0x318e, 0x000c, + 0x4653, 0x0000, 0x0246, 0xffac, 0x0c01, 0x48be, 0x0024, 0x4162, 0x4546, + 0x6642, 0x4055, 0x3501, 0x8024, 0x0000, 0x0087, 0x667c, 0x4057, 0x000c, + 0x41d5, 0x283a, 0x62d5, 0x3501, 0x8024, 0x667c, 0x1c47, 0x3701, 0x8024, + 0x283a, 0x62d5, 0xc67c, 0x0024, 0x0000, 0x0024, 0x283a, 0x62c5, 0x0000, + 0x0024, 0x2a3a, 0x5ec0, 0x3009, 0x3851, 0x3e14, 0xf812, 0x3e12, 0xb817, + 0x3e11, 0x8024, 0x0006, 0x0293, 0x3301, 0x8024, 0x468c, 0x3804, 0x0006, + 0xa057, 0x2801, 0x5a04, 0x0006, 0x0011, 0x469c, 0x0024, 0x3be1, 0x8024, + 0x2801, 0x5a15, 0x0006, 0xc392, 0x3311, 0x0024, 0x33f1, 0x2844, 0x3009, + 0x2bc4, 0x0030, 0x04d2, 0x3311, 0x0024, 0x3a11, 0x0024, 0x3201, 0x8024, + 0x003f, 0xfc04, 0xb64c, 0x0fc4, 0xc648, 0x0024, 0x3a01, 0x0024, 0x3111, + 0x1fd3, 0x6498, 0x07c6, 0x868c, 0x2444, 0x0023, 0xffd2, 0x3901, 0x8e06, + 0x0030, 0x0551, 0x3911, 0x8e06, 0x3961, 0x9c44, 0xf400, 0x44c6, 0xd46c, + 0x1bc4, 0x36f1, 0xbc13, 0x2801, 0x6395, 0x36f2, 0x9817, 0x002b, 0xffd2, + 0x3383, 0x188c, 0x3e01, 0x8c06, 0x0006, 0xa097, 0x3009, 0x1c12, 0x3213, + 0x0024, 0x468c, 0xbc12, 0x002b, 0xffd2, 0xf400, 0x4197, 0x2801, 0x6084, + 0x3713, 0x0024, 0x2801, 0x60c5, 0x37e3, 0x0024, 0x3009, 0x2c17, 0x3383, + 0x0024, 0x3009, 0x0c06, 0x468c, 0x4197, 0x0006, 0xa052, 0x2801, 0x62c4, + 0x3713, 0x2813, 0x2801, 0x6305, 0x37e3, 0x0024, 0x3009, 0x2c17, 0x36f1, + 0x8024, 0x36f2, 0x9817, 0x36f4, 0xd812, 0x2100, 0x0000, 0x3904, 0x5bd1, + 0x2a01, 0x53ce, 0x3e11, 0x7804, 0x0030, 0x0257, 0x3701, 0x0024, 0x0013, + 0x4d05, 0xd45b, 0xe0e1, 0x0007, 0xc795, 0x2801, 0x6b15, 0x0fff, 0xff45, + 0x3511, 0x184c, 0x4488, 0xb808, 0x0006, 0x8a97, 0x2801, 0x6ac5, 0x3009, + 0x1c40, 0x3511, 0x1fc1, 0x0000, 0x0020, 0xac52, 0x1405, 0x6ce2, 0x0024, + 0x0000, 0x0024, 0x2801, 0x6ac1, 0x68c2, 0x0024, 0x291a, 0x8a40, 0x3e10, + 0x0024, 0x2921, 0xca80, 0x3e00, 0x4024, 0x36f3, 0x0024, 0x3009, 0x1bc8, + 0x36f0, 0x1801, 0x3601, 0x5804, 0x3e13, 0x780f, 0x3e13, 0xb808, 0x0008, + 0x9b0f, 0x0001, 0x6dce, 0x2908, 0x9300, 0x0000, 0x004d, 0x36f3, 0x9808, + 0x2000, 0x0000, 0x36f3, 0x580f, 0x0007, 0x81d7, 0x3711, 0x8024, 0x3711, + 0xc024, 0x3700, 0x0024, 0x0000, 0x2001, 0xb012, 0x0024, 0x0034, 0x0000, + 0x2801, 0x7105, 0x0000, 0x01c1, 0x0030, 0x0117, 0x3f00, 0x0024, 0x0014, + 0xc000, 0x0000, 0x01c1, 0x4fce, 0x0024, 0xffea, 0x0024, 0x48b6, 0x0024, + 0x4384, 0x4097, 0xb886, 0x45c6, 0xfede, 0x0024, 0x4db6, 0x0024, 0x466c, + 0x0024, 0x0006, 0xc610, 0x8dd6, 0x8007, 0x0000, 0x00c6, 0xff6e, 0x0024, + 0x48b2, 0x0024, 0x0034, 0x2406, 0xffee, 0x0024, 0x2914, 0xaa80, 0x40b2, + 0x0024, 0xf1c6, 0x0024, 0xf1d6, 0x0024, 0x0000, 0x0201, 0x8d86, 0x0024, + 0x61de, 0x0024, 0x0006, 0xc612, 0x2801, 0x7781, 0x0006, 0xc713, 0x4c86, + 0x0024, 0x2912, 0x1180, 0x0006, 0xc351, 0x0006, 0x0210, 0x2912, 0x0d00, + 0x3810, 0x984c, 0xf200, 0x2043, 0x2808, 0xa000, 0x3800, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, + 0x3811, 0x0006, 0xa090, 0x2912, 0x0d00, 0x3e14, 0xc024, 0x4088, 0x8000, + 0x4080, 0x0024, 0x0007, 0x90d1, 0x2801, 0x7f45, 0x0000, 0x0024, 0x0007, + 0x9051, 0x3100, 0x4024, 0x4100, 0x0024, 0x3900, 0x0024, 0x0007, 0x90d1, + 0x0004, 0x0000, 0x31f0, 0x4024, 0x6014, 0x0400, 0x0000, 0x0024, 0x2801, + 0x8391, 0x4080, 0x0024, 0x0000, 0x0000, 0x2801, 0x8305, 0x0000, 0x0024, + 0x0007, 0x9053, 0x3300, 0x0024, 0x4080, 0x0024, 0x0000, 0x0000, 0x2801, + 0x8398, 0x0000, 0x0024, 0x0007, 0x9051, 0x3900, 0x0024, 0x3200, 0x504c, + 0x6410, 0x0024, 0x3cf0, 0x0000, 0x4080, 0x0024, 0x0006, 0xc691, 0x2801, + 0x9c45, 0x3009, 0x0400, 0x0000, 0x1001, 0x0007, 0x9051, 0x3100, 0x0024, + 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2801, 0x9089, 0x003f, 0xe000, 0x0006, + 0xc693, 0x3900, 0x0c00, 0x3009, 0x0001, 0x6014, 0x0024, 0x0007, 0x1ad0, + 0x2801, 0x9095, 0x3009, 0x0000, 0x4080, 0x0024, 0x0000, 0x0301, 0x2801, + 0x8a85, 0x4090, 0x0024, 0x0000, 0x0024, 0x2801, 0x8b95, 0x0000, 0x0024, + 0x3009, 0x0000, 0xc012, 0x0024, 0x2801, 0x9080, 0x3009, 0x2001, 0x3009, + 0x0000, 0x6012, 0x0024, 0x0000, 0x0341, 0x2801, 0x8d95, 0x0000, 0x0024, + 0x6190, 0x0024, 0x2801, 0x9080, 0x3009, 0x2000, 0x6012, 0x0024, 0x0000, + 0x0381, 0x2801, 0x8f55, 0x0000, 0x0024, 0x6190, 0x0024, 0x2801, 0x9080, + 0x3009, 0x2000, 0x6012, 0x0024, 0x0000, 0x00c0, 0x2801, 0x9095, 0x0000, + 0x0024, 0x3009, 0x2000, 0x0006, 0xa090, 0x3009, 0x0000, 0x4080, 0x0024, + 0x0000, 0x0081, 0x2801, 0x9555, 0x0007, 0x8c13, 0x3300, 0x104c, 0xb010, + 0x0024, 0x0002, 0x8001, 0x2801, 0x97c5, 0x34f0, 0x0024, 0x2801, 0x9540, + 0x0000, 0x0024, 0x0006, 0xc351, 0x3009, 0x0000, 0x6090, 0x0024, 0x3009, + 0x2000, 0x2900, 0x0b80, 0x3009, 0x0405, 0x0006, 0xc6d1, 0x0006, 0xc690, + 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, 0x0024, 0x0006, 0xa093, 0x2801, + 0x93d1, 0xb880, 0x0024, 0x2801, 0xa500, 0x3009, 0x2c00, 0x4040, 0x0024, + 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2801, 0xa518, 0x0000, 0x0024, 0x0006, + 0xc693, 0x3009, 0x0c00, 0x3009, 0x0001, 0x6014, 0x0024, 0x0006, 0xc350, + 0x2801, 0xa501, 0x0000, 0x0024, 0x6090, 0x0024, 0x3009, 0x2c00, 0x3009, + 0x0005, 0x2900, 0x0b80, 0x0001, 0xa508, 0x3009, 0x0400, 0x4080, 0x0024, + 0x0003, 0x8000, 0x2801, 0xa505, 0x0000, 0x0024, 0x6400, 0x0024, 0x0000, + 0x0081, 0x2801, 0xa509, 0x0000, 0x0024, 0x0007, 0x8c13, 0x3300, 0x0024, + 0xb010, 0x0024, 0x0006, 0xc650, 0x2801, 0xa515, 0x0000, 0x0024, 0x0001, + 0x0002, 0x3413, 0x0000, 0x3009, 0x0401, 0x4010, 0x8406, 0x0000, 0x0281, + 0xa010, 0x13c1, 0x4122, 0x0024, 0x0000, 0x03c2, 0x6122, 0x8002, 0x462c, + 0x0024, 0x469c, 0x0024, 0xfee2, 0x0024, 0x48be, 0x0024, 0x6066, 0x8400, + 0x0006, 0xc350, 0x2801, 0xa501, 0x0000, 0x0024, 0x4090, 0x0024, 0x3009, + 0x2400, 0x2900, 0x0b80, 0x3009, 0x0005, 0x0007, 0x1b50, 0x2912, 0x0d00, + 0x3613, 0x0024, 0x3a00, 0x0380, 0x4080, 0x0024, 0x0000, 0x00c1, 0x2801, + 0xadc5, 0x3009, 0x0000, 0xb010, 0x008c, 0x4192, 0x0024, 0x6012, 0x0024, + 0x0006, 0xf051, 0x2801, 0xabd8, 0x3009, 0x0400, 0x0007, 0x1fd1, 0x30e3, + 0x0400, 0x4080, 0x0024, 0x0000, 0x0301, 0x2801, 0xadc5, 0x3009, 0x0000, + 0xb010, 0x0024, 0x0000, 0x0101, 0x6012, 0x0024, 0x0006, 0xf051, 0x2801, + 0xadd5, 0x0000, 0x0024, 0x3023, 0x0400, 0xf200, 0x184c, 0xb880, 0xa400, + 0x3009, 0x2000, 0x3009, 0x0441, 0x3e10, 0x4402, 0x2909, 0xa9c0, 0x3e10, + 0x8024, 0x36e3, 0x0024, 0x36f4, 0xc024, 0x36f4, 0x1811, 0x36f1, 0x9807, + 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, + 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, + 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, + 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xf810, + 0x0001, 0x0010, 0x3e14, 0x7812, 0xb882, 0x3813, 0x2914, 0xbec0, 0x0000, + 0x2200, 0xb886, 0x12cc, 0x2801, 0xba40, 0x3454, 0x8024, 0x0001, 0x0000, + 0x3000, 0x984c, 0x4234, 0xb843, 0xf400, 0x4095, 0x003b, 0xffc2, 0x3500, + 0x4024, 0xb122, 0x0842, 0x4010, 0x0bc3, 0x4010, 0x0024, 0x4010, 0x0024, + 0x4010, 0x0024, 0x4d82, 0x4011, 0x2938, 0x0600, 0xf400, 0x4450, 0x3223, + 0x184c, 0x3210, 0x8024, 0x32d0, 0xc024, 0x2938, 0x0600, 0x4d82, 0x4450, + 0x3243, 0x1bc3, 0x6396, 0x0024, 0x0005, 0xdf90, 0x3000, 0x0024, 0x6302, + 0x0024, 0x0005, 0xe110, 0x2801, 0xb511, 0x0000, 0x0024, 0x2801, 0xc0c0, + 0x4086, 0x0024, 0x3200, 0x930c, 0x6398, 0x1111, 0x4244, 0x0844, 0xf400, + 0x4095, 0x3500, 0x584c, 0x4438, 0x0805, 0x453a, 0x4115, 0x3500, 0x8024, + 0x6122, 0x4155, 0x4280, 0x1404, 0x0001, 0x0002, 0x4244, 0x0024, 0x4244, + 0x0024, 0x4244, 0x0024, 0x4244, 0x0024, 0x2938, 0x2f80, 0xf400, 0x4090, + 0x6396, 0x0024, 0x0005, 0xdf50, 0x3000, 0x0024, 0x6302, 0x0024, 0x0005, + 0xe0d2, 0x2801, 0xbc51, 0x0000, 0x0381, 0x3073, 0x0024, 0x3023, 0x0024, + 0x3000, 0x0024, 0x6012, 0x0024, 0x0001, 0x2212, 0x2801, 0xc5d5, 0x0005, + 0x1453, 0x0001, 0x0011, 0x3093, 0x184c, 0x3000, 0x4024, 0x2900, 0x7680, + 0x3e00, 0x4024, 0x2801, 0xc7c0, 0x36f3, 0x0024, 0x0001, 0x0011, 0x0005, + 0xe3c1, 0x3613, 0x024c, 0x3e10, 0x4024, 0x3000, 0x8024, 0x2900, 0x5a00, + 0x3e00, 0x8024, 0x36e3, 0x0024, 0x36f4, 0xc024, 0x36f4, 0x5812, 0x36f1, + 0xd810, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x3801, 0x0000, 0x00c1, 0xb880, 0xb803, 0x3e10, + 0x904c, 0x3e11, 0x3806, 0x3e11, 0xf810, 0x0006, 0xf450, 0x3e14, 0x7812, + 0x3e14, 0xc024, 0x3cf0, 0x2080, 0x3009, 0x23c0, 0x3009, 0x2380, 0x0000, + 0x0640, 0x3009, 0x2000, 0x2921, 0x9440, 0x0000, 0x00c0, 0x2921, 0xdd40, + 0x3613, 0x0024, 0xf400, 0x4004, 0x0000, 0x01c0, 0x6400, 0x0024, 0x0000, + 0x00c0, 0x2801, 0xeac5, 0x0000, 0x01c1, 0x6412, 0x4100, 0x0006, 0x0581, + 0x2801, 0xe041, 0x4412, 0x0024, 0xf400, 0x4057, 0x3702, 0x0024, 0x2000, + 0x0000, 0x0000, 0x0024, 0x0000, 0x0641, 0x0006, 0xf410, 0x3613, 0x0000, + 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0xd615, 0x0000, 0x0024, 0x3009, + 0x2004, 0x2900, 0xb3c0, 0x3e01, 0x0024, 0x2801, 0xe040, 0x36f3, 0x0024, + 0x0000, 0x0641, 0x0006, 0xf410, 0x3613, 0x0000, 0x6012, 0x0024, 0x0000, + 0x0024, 0x2801, 0xd915, 0x0000, 0x0024, 0x3009, 0x2004, 0x2900, 0xa1c0, + 0x3e01, 0x0024, 0x2801, 0xe040, 0x36f3, 0x0024, 0x0006, 0xf450, 0x3613, + 0x0000, 0x6090, 0x3804, 0x2900, 0xb3c0, 0x3009, 0x2000, 0x2801, 0xe040, + 0x36f3, 0x0024, 0x2923, 0x4f00, 0x0007, 0x2050, 0x2801, 0xe040, 0x3009, + 0x2000, 0x2923, 0x7580, 0x0001, 0xe048, 0x34d3, 0x184c, 0x3430, 0x0024, + 0x2922, 0x4fc0, 0x3e00, 0x0024, 0x2801, 0xe040, 0x36f3, 0x0024, 0x0007, + 0x2050, 0x0000, 0x3fc0, 0x3613, 0x0024, 0x2923, 0x8480, 0x3e00, 0x0024, + 0x36f3, 0x2000, 0x0000, 0x1800, 0x3413, 0x0024, 0xf400, 0x4510, 0x34f0, + 0x4024, 0x6192, 0x0024, 0x6014, 0x2001, 0x0007, 0x2051, 0x2801, 0xe2c1, + 0x0000, 0x0280, 0x3009, 0x2400, 0x3009, 0x0400, 0x4080, 0x0024, 0x0006, + 0xf352, 0x2801, 0xebd5, 0x3009, 0x0842, 0x3009, 0x0bc3, 0x4d86, 0x0024, + 0x0000, 0x0201, 0x2801, 0xe705, 0x0030, 0x0013, 0x0006, 0x8a93, 0x3009, + 0x0c40, 0x3009, 0x0fc1, 0x6cde, 0x0024, 0x0000, 0x0201, 0x2801, 0xebc1, + 0x0030, 0x0013, 0x3300, 0x0024, 0xb010, 0x0024, 0x0000, 0x0100, 0x2801, + 0xebd5, 0x0000, 0x00c1, 0x2921, 0x9440, 0x3613, 0x0024, 0x2921, 0xdd40, + 0x3613, 0x0024, 0xf400, 0x4004, 0x0000, 0x01c0, 0x6400, 0x0024, 0x0000, + 0x01c1, 0x2801, 0xd215, 0x0000, 0x00c0, 0x2921, 0x9440, 0x3613, 0x0024, + 0x2921, 0xc300, 0x0000, 0x0024, 0x36f4, 0xc024, 0x36f4, 0x5812, 0x36f1, + 0xd810, 0x36f1, 0x1806, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, + 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3615, 0x0024, + 0x0000, 0x800a, 0x3e10, 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7810, 0x3e14, + 0x7812, 0x3e14, 0xc024, 0x2922, 0x1880, 0x0000, 0x0180, 0x2921, 0xdd40, + 0x6892, 0x184c, 0x4080, 0x0024, 0x0000, 0x0024, 0x2801, 0xf3c5, 0x0000, + 0x0024, 0x2802, 0x2f40, 0xb880, 0x0024, 0x2921, 0xdd40, 0x6892, 0x184c, + 0x4080, 0x0024, 0x0000, 0x0181, 0x2801, 0xf5d5, 0x0000, 0x0024, 0x2802, + 0x2f40, 0xb880, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0101, 0x2801, 0xf7c5, 0x0000, 0x0024, 0x2802, 0x2f40, 0xb880, + 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x4080, 0x0024, 0x0000, 0x00c1, + 0x2801, 0xf9c5, 0x0000, 0x0024, 0x2802, 0x2f40, 0xb880, 0x0024, 0x2921, + 0xdd40, 0x3613, 0x0024, 0x4080, 0x0024, 0x0000, 0x0141, 0x2801, 0xfbc5, + 0x0006, 0xf250, 0x2802, 0x2f40, 0xb880, 0x0024, 0x2921, 0xdd40, 0x3613, + 0x0024, 0x0000, 0x0101, 0x2921, 0xdd40, 0x3613, 0x2000, 0x0000, 0x03c1, + 0x6012, 0x03cc, 0x3613, 0x2000, 0x2802, 0x0115, 0x0006, 0xf051, 0x3009, + 0x3841, 0x2921, 0xdd40, 0x0000, 0x0201, 0xb080, 0x024c, 0x3009, 0x2000, + 0x2921, 0xdd40, 0x0000, 0x0401, 0x3009, 0x0401, 0xc100, 0x0024, 0x2802, + 0x0240, 0x3009, 0x2400, 0x3009, 0x0002, 0x2920, 0x5d00, 0x3e00, 0x8024, + 0x36f3, 0x024c, 0x3009, 0x2000, 0x0000, 0x0101, 0x2921, 0xdd40, 0x3613, + 0x0024, 0x0000, 0x0141, 0x3013, 0x0024, 0x3009, 0x21c0, 0x3009, 0x0000, + 0x6012, 0x0024, 0x0007, 0x1b51, 0x2802, 0x1395, 0x0000, 0x0101, 0x0007, + 0xc251, 0x2921, 0xdd40, 0x3613, 0x0024, 0x0000, 0x03c1, 0x6012, 0x2400, + 0x3100, 0x984c, 0x2802, 0x0ad5, 0x0007, 0xc292, 0x3009, 0x3841, 0x2921, + 0xdd40, 0x0000, 0x0201, 0x4082, 0x044c, 0xb080, 0x0024, 0x3910, 0x0024, + 0x39f0, 0x7841, 0x2921, 0xdd40, 0x0000, 0x0401, 0x3211, 0x1bcc, 0xb182, + 0x0bc5, 0xcec2, 0x0024, 0x3a10, 0x0024, 0x2802, 0x0c00, 0x3af0, 0x4024, + 0x2920, 0x5d00, 0x3e00, 0x8024, 0x36f3, 0x044c, 0x3910, 0x0024, 0x39f0, + 0x4024, 0x0007, 0x1b52, 0x0000, 0x0141, 0x2921, 0xdd40, 0x3613, 0x0024, + 0x3111, 0x2240, 0xb880, 0x03cc, 0x31f1, 0x6800, 0xb182, 0x8000, 0x6ce6, + 0x0024, 0x002e, 0xe002, 0x2802, 0x1a85, 0xb886, 0x0024, 0x6de2, 0x0b8c, + 0x0000, 0x00c1, 0x2802, 0x1251, 0x3009, 0x0800, 0xb010, 0x0024, 0x4192, + 0x0024, 0x6012, 0x0024, 0x0007, 0x1b52, 0x2802, 0x1258, 0x0000, 0x0024, + 0x6890, 0xa004, 0x2802, 0x1a80, 0x3009, 0x2800, 0x4e82, 0x0024, 0x0000, + 0x0020, 0xf2c2, 0x0024, 0x2802, 0x1a80, 0x3009, 0x2000, 0x3009, 0x07c0, + 0x4080, 0x0024, 0x0000, 0x0024, 0x2802, 0x1a85, 0x0000, 0x0024, 0x3093, + 0x0400, 0x4080, 0x03cc, 0x0017, 0x7001, 0x2802, 0x1995, 0x3009, 0x0000, + 0x6012, 0x0024, 0x0007, 0x1b50, 0x2802, 0x1901, 0xb880, 0x0024, 0x0000, + 0x00c1, 0x31f3, 0x0024, 0x3009, 0x0400, 0xb010, 0x0024, 0x4080, 0x0024, + 0x0000, 0x0000, 0x2802, 0x1989, 0x0000, 0x0024, 0x2802, 0x1a80, 0x3009, + 0x2000, 0x0006, 0xf050, 0x3009, 0x0000, 0x4000, 0x0024, 0x3009, 0x2000, + 0x0000, 0x0081, 0x0006, 0xf250, 0x3009, 0x0000, 0x6012, 0x0024, 0x0007, + 0xc151, 0x2802, 0x1cc5, 0x0000, 0x0024, 0x2802, 0x2f40, 0xb880, 0x0024, + 0x2921, 0xdd40, 0x6892, 0x184c, 0x6892, 0x2400, 0x2921, 0xdd40, 0x3009, + 0x184c, 0x4080, 0x0024, 0x0000, 0x0381, 0x2802, 0x1f85, 0x0000, 0x0024, + 0x2921, 0xdd40, 0x3613, 0x0024, 0x2921, 0xdd40, 0x6892, 0x184c, 0x4080, + 0x0024, 0x0000, 0x0240, 0x2802, 0x2205, 0x0000, 0x00c1, 0x2921, 0xdd40, + 0x6892, 0x184c, 0x0000, 0x00c1, 0x0000, 0x0240, 0x0006, 0x0752, 0x2922, + 0x1880, 0x3613, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x4080, 0x2800, + 0x0000, 0x0201, 0x2802, 0x2515, 0x3613, 0x0024, 0x2921, 0xdd40, 0x0002, + 0x2788, 0x3613, 0x0024, 0x4090, 0x1bcc, 0x0000, 0x0241, 0x2802, 0x2715, + 0x0006, 0x07d3, 0x2921, 0xdd40, 0x3613, 0x0024, 0x2802, 0x2780, 0x3b00, + 0x0024, 0x2802, 0x2f40, 0xb880, 0x0024, 0x0006, 0x0813, 0xb880, 0x184c, + 0x2921, 0xdd40, 0x6892, 0x2c00, 0x4080, 0x0024, 0x0006, 0x0810, 0x2802, + 0x2d05, 0x0000, 0x4003, 0x3000, 0x184c, 0xff86, 0x0024, 0x48b6, 0x0024, + 0x2921, 0xdd40, 0x6892, 0x2002, 0x0000, 0x0201, 0x2921, 0xdd40, 0x4088, + 0x184c, 0x3000, 0x4024, 0x4100, 0x0024, 0x4488, 0x2000, 0x0000, 0x4003, + 0x2802, 0x2995, 0x0006, 0x0810, 0x2921, 0xdd40, 0x6892, 0x184c, 0x4080, + 0x0024, 0x0000, 0x0201, 0x2802, 0x2f05, 0x0000, 0x0024, 0x2921, 0xdd40, + 0x3613, 0x0024, 0x6890, 0x0024, 0x36f4, 0xc024, 0x36f4, 0x5812, 0x36f1, + 0x5810, 0x36f0, 0xd804, 0x36f0, 0x5802, 0x3405, 0x9014, 0x36f3, 0x0024, + 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x0000, 0x0081, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, + 0xb807, 0x3e14, 0x3811, 0x0006, 0xf250, 0x3e04, 0xb813, 0x3009, 0x0000, + 0x6012, 0x0024, 0x003f, 0xff01, 0x2802, 0x3a05, 0x0006, 0x07d1, 0x6194, + 0x0400, 0x0000, 0x0041, 0xa020, 0x984c, 0x0000, 0x01c2, 0xfe02, 0x0024, + 0x48b2, 0x0024, 0x3e10, 0x0024, 0x2921, 0xca80, 0x3e00, 0x4024, 0x3100, + 0x5bcc, 0x2921, 0xdd40, 0xb122, 0x0024, 0x291a, 0x8a40, 0x0002, 0x4c08, + 0x0007, 0x2052, 0x0006, 0x8a93, 0x3100, 0x184c, 0xa010, 0x0024, 0x0000, + 0x0041, 0x6090, 0x0024, 0x2922, 0x1880, 0x6090, 0x0024, 0xb880, 0x010c, + 0x3100, 0x2800, 0xfe02, 0x8c44, 0x3613, 0x0fc5, 0x4eb2, 0x0024, 0x3009, + 0x2040, 0x0000, 0x00c0, 0x2921, 0xbb80, 0x3e00, 0x23c1, 0x0000, 0x01c1, + 0x6012, 0x0024, 0x0003, 0xf680, 0x2802, 0x4055, 0x0000, 0x0024, 0x36f3, + 0x0024, 0x291a, 0x8a40, 0x0002, 0x4c08, 0x2901, 0xca80, 0x3e00, 0x0024, + 0x3413, 0x0040, 0x36f3, 0x03c1, 0x3009, 0x0c44, 0x3009, 0x0fc5, 0x6ce2, + 0x0024, 0x3c10, 0x0024, 0xbc82, 0x33c1, 0x3410, 0x2040, 0x34e0, 0x63c1, + 0x4c82, 0x0024, 0x0000, 0x0024, 0x2802, 0x4909, 0x4c82, 0x0024, 0x0000, + 0x01c4, 0x4c86, 0x184c, 0x003f, 0xff40, 0xad06, 0x0024, 0x3e10, 0x8024, + 0x2921, 0xca80, 0x3e00, 0xc024, 0x36f3, 0x0024, 0x2921, 0x9440, 0x0000, + 0x0080, 0xb88a, 0x104c, 0x3410, 0x0c46, 0x34e0, 0x4fc7, 0xbce2, 0x984c, + 0x4cf2, 0x0024, 0x3e10, 0x0024, 0x2921, 0x9780, 0x3e00, 0x4024, 0x2802, + 0x4b00, 0x36e3, 0x0024, 0x0000, 0x0024, 0x2802, 0x4b18, 0x0000, 0x0024, + 0x4ce6, 0x184c, 0x3e10, 0x8024, 0x2921, 0x9780, 0x3e00, 0xc024, 0x36e3, + 0x0024, 0x291a, 0x8a40, 0x0000, 0x0100, 0x2922, 0x1880, 0x3613, 0x0024, + 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, + 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, + 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, 0x0000, 0x800a, 0x3e10, 0x7802, + 0x3e10, 0xf804, 0x3e14, 0x3811, 0x0006, 0x8a91, 0x0006, 0x0790, 0x3e14, + 0xb813, 0x0007, 0x8b52, 0x3e13, 0xf80e, 0x3e03, 0x504c, 0xb880, 0x0024, + 0x3c00, 0x33c0, 0x2921, 0xb380, 0x3800, 0x0024, 0x2920, 0x6a00, 0x0030, + 0x0253, 0x0000, 0x0400, 0xb882, 0xa440, 0xb880, 0xa7c1, 0x3a00, 0x0024, + 0x0013, 0x1040, 0x3b00, 0x0024, 0x0000, 0x0180, 0x2922, 0x1880, 0x3613, + 0x0024, 0x4f82, 0x0024, 0x003f, 0xf801, 0xb010, 0x0024, 0x0015, 0xb801, + 0x6012, 0x0024, 0x0007, 0x8a50, 0x2802, 0x73d5, 0x0000, 0x0201, 0x0006, + 0x8a90, 0x2921, 0xdd40, 0x3613, 0x0024, 0x003f, 0xfe00, 0x3613, 0x0042, + 0xb882, 0x83c3, 0xbdc2, 0x0024, 0x3009, 0x2040, 0x2921, 0xdd40, 0x6892, + 0xa3c1, 0x4080, 0x0024, 0x0000, 0x0024, 0x2802, 0x5e95, 0x0000, 0x0024, + 0x2901, 0xee80, 0x0006, 0x0791, 0x4080, 0x2400, 0x0006, 0xf052, 0x2802, + 0x5e85, 0x0000, 0x0024, 0x3613, 0x0841, 0x3e10, 0x4802, 0x2909, 0xa9c0, + 0x3e10, 0x8024, 0x36e3, 0x0024, 0x0006, 0x0791, 0x3100, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0024, 0x2921, 0xc305, 0x0002, 0x6f48, 0x0006, 0x0752, + 0xb880, 0x104c, 0x3613, 0x33c0, 0x2922, 0x1880, 0x0000, 0x0100, 0x3200, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2902, 0x31d5, 0x0002, 0x67c8, + 0x0006, 0x07d3, 0xb880, 0x0024, 0x0006, 0x07d0, 0x3b00, 0x0024, 0x0000, + 0x0201, 0x2921, 0xdd40, 0x3613, 0x0024, 0x0000, 0x00c1, 0x3423, 0x0024, + 0x3c00, 0x0024, 0xa010, 0x0001, 0x4100, 0x0024, 0x0000, 0x3fc1, 0x3800, + 0x0024, 0x34e0, 0x0024, 0x6012, 0x0024, 0x0006, 0x07d0, 0x2802, 0x6385, + 0x0000, 0x0024, 0x2902, 0x31c0, 0x0000, 0x0024, 0x0006, 0x0810, 0x3000, + 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, 0x2802, 0x6ec5, 0x0000, 0x0024, + 0xf200, 0x184c, 0xf200, 0x0024, 0xf200, 0x0024, 0xb182, 0x3840, 0x2921, + 0xca80, 0x3e00, 0x4024, 0x0000, 0x01c1, 0x291a, 0x8a40, 0x36e3, 0x0024, + 0xb888, 0x4411, 0x3000, 0x0024, 0xb012, 0x0024, 0x6410, 0x2001, 0x0000, + 0x0024, 0x2802, 0x6ec1, 0x0000, 0x0024, 0x4192, 0x0024, 0x2402, 0x6e81, + 0x0000, 0x0024, 0x2921, 0xdd40, 0x6892, 0x184c, 0x6498, 0x0024, 0x2921, + 0xc300, 0x0000, 0x0024, 0x291a, 0x8a40, 0x3413, 0x0024, 0xf400, 0x4512, + 0x0030, 0x0010, 0x0000, 0x0201, 0x2900, 0x0c80, 0x34f3, 0x0024, 0x3000, + 0x0024, 0xb010, 0x0024, 0x0000, 0x0100, 0x2802, 0x8095, 0x0000, 0x0401, + 0x2922, 0x1880, 0x3613, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0x2802, + 0x7ec0, 0xb78e, 0x4006, 0x3000, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2802, 0x8089, 0xf292, 0x0024, 0x6012, 0x904c, 0x0006, 0x0791, 0x2802, + 0x7718, 0x3100, 0x0024, 0x3000, 0x0024, 0x4090, 0x0024, 0x3800, 0x0024, + 0x3100, 0x0024, 0x4080, 0x4512, 0x34f3, 0x184c, 0x2802, 0x79d5, 0x0007, + 0x0553, 0x36f3, 0x0800, 0x6090, 0x0024, 0x4080, 0xa800, 0x0000, 0x0024, + 0x2802, 0x8088, 0x0000, 0x0024, 0x3009, 0x184c, 0x0006, 0xf312, 0x4ffe, + 0xb841, 0x2921, 0xdd40, 0x6892, 0x41c7, 0xb182, 0x9bcc, 0x291a, 0x8a40, + 0xcfce, 0x0024, 0x0004, 0x0001, 0xb880, 0x010c, 0x6890, 0x2000, 0x0007, + 0x80d0, 0xb880, 0xa800, 0x3000, 0x2c00, 0x0007, 0x1ad0, 0xff82, 0x0024, + 0x48b2, 0x0024, 0xf400, 0x4040, 0x0000, 0x03c1, 0xb010, 0x0024, 0x3009, + 0x2000, 0x0000, 0x0201, 0x0030, 0x0010, 0x3000, 0x0024, 0xb010, 0x0024, + 0x0000, 0x0180, 0x2802, 0x55c5, 0x0000, 0x0024, 0x6890, 0x1bcd, 0x36f3, + 0xd80e, 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f0, 0xd804, 0x36f0, 0x5802, + 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, + 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, + 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x0012, 0x5103, 0x3e11, + 0x3805, 0x3e11, 0xb807, 0x3e14, 0x380d, 0x0030, 0x0250, 0x3e13, 0xf80e, + 0xbe8b, 0x83e0, 0x290c, 0x4840, 0x3613, 0x0024, 0x290c, 0x4840, 0x4086, + 0x984c, 0x0000, 0x00ce, 0x2402, 0x8a8e, 0x3009, 0x1bc0, 0x0000, 0x01c3, + 0xae3a, 0x184c, 0x0000, 0x0043, 0x3009, 0x3842, 0x290c, 0x4840, 0x3009, + 0x3840, 0x4084, 0x9bc0, 0xfe26, 0x9bc2, 0xceba, 0x0024, 0x4e8e, 0x0024, + 0x4e9a, 0x0024, 0x4f8e, 0x0024, 0x0000, 0x0102, 0x2802, 0x8fc5, 0x0030, + 0x0010, 0x0000, 0x0206, 0x3613, 0x0024, 0x290c, 0x4840, 0x3009, 0x3840, + 0x3000, 0xdbc0, 0xb366, 0x0024, 0x0000, 0x0024, 0x2802, 0x8fd5, 0x4e8e, + 0x0024, 0x4e9a, 0x0024, 0x4f8e, 0x0024, 0x0030, 0x0010, 0x2802, 0x8c95, + 0x0000, 0x0206, 0x36f3, 0xd80e, 0x36f4, 0x180d, 0x36f1, 0x9807, 0x36f1, + 0x1805, 0x36f0, 0x9803, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, + 0x2000, 0x0000, 0x36f2, 0x9817, 0x0007, 0x0001, /*copy 1*/ + 0x802e, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x6480, 0x0007, 0x0001, /*copy 1*/ + 0x8030, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x1b40, 0x0007, 0x0001, /*copy 1*/ + 0x8028, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x144e, 0x0007, 0x0001, /*copy 1*/ + 0x8032, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x7980, 0x0007, 0x0001, /*copy 1*/ + 0x3580, 0x0006, 0x8038, 0x0000, /*Rle(56)*/ + 0x0007, 0x0001, /*copy 1*/ + 0xfab3, 0x0006, 0x01a4, /*copy 420*/ + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0xffff, 0xfffe, 0xfffb, 0xfff9, + 0xfff5, 0xfff2, 0xffed, 0xffe8, 0xffe3, 0xffde, 0xffd8, 0xffd3, 0xffce, + 0xffca, 0xffc7, 0xffc4, 0xffc4, 0xffc5, 0xffc7, 0xffcc, 0xffd3, 0xffdc, + 0xffe6, 0xfff3, 0x0001, 0x0010, 0x001f, 0x002f, 0x003f, 0x004e, 0x005b, + 0x0066, 0x006f, 0x0074, 0x0075, 0x0072, 0x006b, 0x005f, 0x004f, 0x003c, + 0x0024, 0x0009, 0xffed, 0xffcf, 0xffb0, 0xff93, 0xff77, 0xff5f, 0xff4c, + 0xff3d, 0xff35, 0xff34, 0xff3b, 0xff4a, 0xff60, 0xff7e, 0xffa2, 0xffcd, + 0xfffc, 0x002e, 0x0061, 0x0094, 0x00c4, 0x00f0, 0x0114, 0x0131, 0x0144, + 0x014b, 0x0146, 0x0134, 0x0116, 0x00eb, 0x00b5, 0x0075, 0x002c, 0xffde, + 0xff8e, 0xff3d, 0xfeef, 0xfea8, 0xfe6a, 0xfe39, 0xfe16, 0xfe05, 0xfe06, + 0xfe1b, 0xfe43, 0xfe7f, 0xfecd, 0xff2a, 0xff95, 0x0009, 0x0082, 0x00fd, + 0x0173, 0x01e1, 0x0242, 0x0292, 0x02cc, 0x02ec, 0x02f2, 0x02da, 0x02a5, + 0x0253, 0x01e7, 0x0162, 0x00c9, 0x0021, 0xff70, 0xfebc, 0xfe0c, 0xfd68, + 0xfcd5, 0xfc5b, 0xfc00, 0xfbc9, 0xfbb8, 0xfbd2, 0xfc16, 0xfc85, 0xfd1b, + 0xfdd6, 0xfeae, 0xff9e, 0x009c, 0x01a0, 0x02a1, 0x0392, 0x046c, 0x0523, + 0x05b0, 0x060a, 0x062c, 0x0613, 0x05bb, 0x0526, 0x0456, 0x0351, 0x021f, + 0x00c9, 0xff5a, 0xfde1, 0xfc6a, 0xfb05, 0xf9c0, 0xf8aa, 0xf7d0, 0xf73d, + 0xf6fa, 0xf70f, 0xf77e, 0xf848, 0xf96b, 0xfadf, 0xfc9a, 0xfe8f, 0x00ad, + 0x02e3, 0x051a, 0x073f, 0x0939, 0x0af4, 0x0c5a, 0x0d59, 0x0de1, 0x0de5, + 0x0d5c, 0x0c44, 0x0a9e, 0x0870, 0x05c7, 0x02b4, 0xff4e, 0xfbaf, 0xf7f8, + 0xf449, 0xf0c7, 0xed98, 0xeae0, 0xe8c4, 0xe765, 0xe6e3, 0xe756, 0xe8d2, + 0xeb67, 0xef19, 0xf3e9, 0xf9cd, 0x00b5, 0x088a, 0x112b, 0x1a72, 0x2435, + 0x2e42, 0x3866, 0x426b, 0x4c1b, 0x553e, 0x5da2, 0x6516, 0x6b6f, 0x7087, + 0x7441, 0x7686, 0x774a, 0x7686, 0x7441, 0x7087, 0x6b6f, 0x6516, 0x5da2, + 0x553e, 0x4c1b, 0x426b, 0x3866, 0x2e42, 0x2435, 0x1a72, 0x112b, 0x088a, + 0x00b5, 0xf9cd, 0xf3e9, 0xef19, 0xeb67, 0xe8d2, 0xe756, 0xe6e3, 0xe765, + 0xe8c4, 0xeae0, 0xed98, 0xf0c7, 0xf449, 0xf7f8, 0xfbaf, 0xff4e, 0x02b4, + 0x05c7, 0x0870, 0x0a9e, 0x0c44, 0x0d5c, 0x0de5, 0x0de1, 0x0d59, 0x0c5a, + 0x0af4, 0x0939, 0x073f, 0x051a, 0x02e3, 0x00ad, 0xfe8f, 0xfc9a, 0xfadf, + 0xf96b, 0xf848, 0xf77e, 0xf70f, 0xf6fa, 0xf73d, 0xf7d0, 0xf8aa, 0xf9c0, + 0xfb05, 0xfc6a, 0xfde1, 0xff5a, 0x00c9, 0x021f, 0x0351, 0x0456, 0x0526, + 0x05bb, 0x0613, 0x062c, 0x060a, 0x05b0, 0x0523, 0x046c, 0x0392, 0x02a1, + 0x01a0, 0x009c, 0xff9e, 0xfeae, 0xfdd6, 0xfd1b, 0xfc85, 0xfc16, 0xfbd2, + 0xfbb8, 0xfbc9, 0xfc00, 0xfc5b, 0xfcd5, 0xfd68, 0xfe0c, 0xfebc, 0xff70, + 0x0021, 0x00c9, 0x0162, 0x01e7, 0x0253, 0x02a5, 0x02da, 0x02f2, 0x02ec, + 0x02cc, 0x0292, 0x0242, 0x01e1, 0x0173, 0x00fd, 0x0082, 0x0009, 0xff95, + 0xff2a, 0xfecd, 0xfe7f, 0xfe43, 0xfe1b, 0xfe06, 0xfe05, 0xfe16, 0xfe39, + 0xfe6a, 0xfea8, 0xfeef, 0xff3d, 0xff8e, 0xffde, 0x002c, 0x0075, 0x00b5, + 0x00eb, 0x0116, 0x0134, 0x0146, 0x014b, 0x0144, 0x0131, 0x0114, 0x00f0, + 0x00c4, 0x0094, 0x0061, 0x002e, 0xfffc, 0xffcd, 0xffa2, 0xff7e, 0xff60, + 0xff4a, 0xff3b, 0xff34, 0xff35, 0xff3d, 0xff4c, 0xff5f, 0xff77, 0xff93, + 0xffb0, 0xffcf, 0xffed, 0x0009, 0x0024, 0x003c, 0x004f, 0x005f, 0x006b, + 0x0072, 0x0075, 0x0074, 0x006f, 0x0066, 0x005b, 0x004e, 0x003f, 0x002f, + 0x001f, 0x0010, 0x0001, 0xfff3, 0xffe6, 0xffdc, 0xffd3, 0xffcc, 0xffc7, + 0xffc5, 0xffc4, 0xffc4, 0xffc7, 0xffca, 0xffce, 0xffd3, 0xffd8, 0xffde, + 0xffe3, 0xffe8, 0xffed, 0xfff2, 0xfff5, 0xfff9, 0xfffb, 0xfffe, 0xffff, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0007, 0x0001, /*copy 1*/ + 0x180b, 0x0006, 0x0012, /*copy 18*/ + 0x000f, 0x0010, 0x001c, 0xfab3, 0x3580, 0x8037, 0xa037, 0x0001, 0x0000, + 0x3580, 0x01a4, 0x0750, 0x075c, 0x076f, 0x0768, 0x0773, 0x0775, 0x077b, + 0x000a, 0x0001, /*copy 1*/ + 0x0050, +#define PLUGIN_SIZE 5594 +#ifndef SKIP_PLUGIN_VARNAME +}; +#endif diff --git a/targets/esp32/components/VS1053/include/patches_pitch.h b/targets/esp32/components/VS1053/include/patches_pitch.h new file mode 100644 index 00000000..5c2effe7 --- /dev/null +++ b/targets/esp32/components/VS1053/include/patches_pitch.h @@ -0,0 +1,688 @@ + +#ifndef SKIP_PLUGIN_VARNAME +const unsigned short PLUGIN[] = { + /* Compressed plugin */ +#endif + 0x0007, 0x0001, /*copy 1*/ + 0x8050, 0x0006, 0x0020, /*copy 32*/ + 0x2a00, 0xc000, 0x2a02, 0x75c0, 0x3e12, 0xb817, 0x3e14, 0xf812, 0x3e01, + 0xb811, 0x0007, 0x9717, 0x0020, 0xffd2, 0x0030, 0x11d1, 0x3111, 0x8024, + 0x3704, 0xc024, 0x3b81, 0x8024, 0x3101, 0x8024, 0x3b81, 0x8024, 0x3f04, + 0xc024, 0x2808, 0x4800, 0x36f1, 0x9811, 0x0007, 0x0001, /*copy 1*/ + 0x8060, 0x0006, 0x0516, /*copy 1302*/ + 0xf400, 0x4095, 0x0000, 0x02c2, 0x6124, 0x0024, 0x0000, 0x0024, 0x2800, + 0x1ac5, 0x4192, 0x4542, 0x0000, 0x0041, 0x2000, 0x0015, 0x0030, 0x0317, + 0x2000, 0x0000, 0x3f00, 0x4024, 0x2000, 0x0000, 0x0000, 0x0000, 0x3e12, + 0x3800, 0x3e00, 0xb804, 0x0030, 0x0015, 0x0007, 0x8257, 0x3700, 0x984c, + 0xf224, 0x1444, 0xf224, 0x0024, 0x0008, 0x0002, 0x2910, 0x0181, 0x0000, + 0x1bc8, 0xb428, 0x1402, 0x0000, 0x8004, 0x2910, 0x0195, 0x0000, 0x1bc8, + 0xb428, 0x0024, 0x0006, 0x0095, 0x2800, 0x2945, 0x3e13, 0x780e, 0x3e11, + 0x7803, 0x3e13, 0xf806, 0x3e11, 0xf801, 0x3510, 0xb808, 0x003f, 0xe004, + 0xfec4, 0x3800, 0x48be, 0x17c3, 0xfec6, 0x41c2, 0x48be, 0x4497, 0x4090, + 0x1c46, 0xf06c, 0x0024, 0x2400, 0x2580, 0x6090, 0x41c3, 0x6628, 0x1c47, + 0x0000, 0x0024, 0x2800, 0x2449, 0xf07e, 0x0024, 0xf400, 0x4182, 0x673a, + 0x1c46, 0x0000, 0x0024, 0x2800, 0x2589, 0xf06c, 0x0024, 0xf400, 0x41c3, + 0x0000, 0x0024, 0x4224, 0x3442, 0x2902, 0xb7c0, 0x4336, 0x37c3, 0x0000, + 0x1805, 0x2902, 0xb7c0, 0x4508, 0x40c2, 0x450a, 0x9808, 0x0000, 0x0207, + 0xa478, 0x1bc0, 0xc45a, 0x1807, 0x0030, 0x03d5, 0x3d01, 0x5bc1, 0x36f3, + 0xd806, 0x3601, 0x5803, 0x36f3, 0x0024, 0x36f3, 0x580e, 0x0007, 0x8257, + 0x0000, 0x6004, 0x3730, 0x8024, 0xb244, 0x1c04, 0xd428, 0x3c02, 0x0006, + 0xc717, 0x2800, 0x2d05, 0x4284, 0x0024, 0x3613, 0x3c02, 0x0006, 0xc357, + 0x2901, 0x6b00, 0x3e11, 0x5c05, 0x4284, 0x1bc5, 0x0007, 0x8257, 0x2800, + 0x3285, 0x0002, 0x0001, 0x3701, 0x0024, 0x0006, 0xc357, 0xb412, 0x9c02, + 0x002e, 0xe001, 0x2800, 0x3005, 0x6212, 0x0024, 0x0000, 0x0024, 0x2800, + 0x3295, 0x0000, 0x0024, 0x0030, 0x0117, 0x3f00, 0x0024, 0x3613, 0x0024, + 0x3e10, 0x3813, 0x3e14, 0x8024, 0x3e04, 0x8024, 0x2900, 0x4b40, 0x0006, + 0x02d3, 0x36e3, 0x0024, 0x3009, 0x1bd3, 0x0007, 0x8257, 0x3700, 0x8024, + 0xf224, 0x0024, 0x0000, 0x0024, 0x2800, 0x3491, 0x3600, 0x9844, 0x2900, + 0x3a40, 0x0000, 0x3508, 0x2911, 0xf140, 0x0000, 0x0024, 0x0030, 0x0057, + 0x3700, 0x0024, 0xf200, 0x4595, 0x0fff, 0xfe02, 0xa024, 0x164c, 0x8000, + 0x17cc, 0x3f00, 0x0024, 0x3500, 0x0024, 0x0021, 0x6d82, 0xd024, 0x44c0, + 0x0006, 0xa402, 0x2800, 0x3955, 0xd024, 0x0024, 0x0000, 0x0000, 0x2800, + 0x3955, 0x000b, 0x6d57, 0x3009, 0x3c00, 0x36f0, 0x8024, 0x36f2, 0x1800, + 0x2000, 0x0000, 0x0000, 0x0024, 0x3e14, 0x7810, 0x3e13, 0xb80d, 0x3e13, + 0xf80a, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0xf801, + 0x3e15, 0x3815, 0x0001, 0x000a, 0x0006, 0xc4d7, 0xbf8e, 0x9c42, 0x3e01, + 0x9c03, 0x0006, 0xa017, 0x0023, 0xffd1, 0x0007, 0x8250, 0x0fff, 0xfd85, + 0x3001, 0x0024, 0xa45a, 0x4494, 0x0000, 0x0093, 0x2800, 0x4091, 0xf25a, + 0x104c, 0x34f3, 0x0024, 0x2800, 0x4091, 0x0000, 0x0024, 0x3413, 0x084c, + 0x0000, 0x0095, 0x3281, 0xf806, 0x4091, 0x4d64, 0x2400, 0x42c0, 0x4efa, + 0x9c10, 0xf1eb, 0x6061, 0xfe55, 0x2f66, 0x5653, 0x4d64, 0x48b2, 0xa201, + 0x4efa, 0xa201, 0x36f3, 0x3c10, 0x36f5, 0x1815, 0x36f4, 0xd801, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0xd80a, 0x36f3, 0x980d, + 0x2000, 0x0000, 0x36f4, 0x5810, 0x36f3, 0x0024, 0x3009, 0x3848, 0x3e14, + 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, 0x2915, 0x94c0, + 0x0001, 0xcc11, 0x36f0, 0x0024, 0x2927, 0x9e40, 0x3604, 0x1811, 0x3613, + 0x0024, 0x3e14, 0x3811, 0x3e00, 0x0024, 0x0000, 0x4000, 0x0001, 0x0010, + 0x2915, 0x94c0, 0x0001, 0xcc11, 0x36f0, 0x0024, 0x36f4, 0x1811, 0x3009, + 0x1808, 0x2000, 0x0000, 0x0000, 0x190d, 0x3613, 0x0024, 0x3e22, 0xb815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e13, 0x7801, 0x3e10, + 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x3e14, 0xb813, + 0x3e03, 0xf80e, 0xb488, 0x44d5, 0x3543, 0x134c, 0x34e5, 0xc024, 0x3524, + 0x8024, 0x35a4, 0xc024, 0x3710, 0x8a0c, 0x3540, 0x4a0c, 0x3d44, 0x8024, + 0x3a10, 0x8024, 0x3590, 0x0024, 0x4010, 0x15c1, 0x6010, 0x3400, 0x3710, + 0x8024, 0x2800, 0x5704, 0x3af0, 0x8024, 0x3df0, 0x0024, 0x3591, 0x4024, + 0x3530, 0x4024, 0x4192, 0x4050, 0x6100, 0x1482, 0x4020, 0x1753, 0xbf8e, + 0x1582, 0x4294, 0x4011, 0xbd86, 0x408e, 0x2400, 0x550e, 0xfe6d, 0x2819, + 0x520e, 0x0a00, 0x5207, 0x2819, 0x4fbe, 0x0024, 0xad56, 0x904c, 0xaf5e, + 0x1010, 0xf7d4, 0x0024, 0xf7fc, 0x2042, 0x6498, 0x2046, 0x3cf4, 0x0024, + 0x3400, 0x170c, 0x4090, 0x1492, 0x35a4, 0xc024, 0x2800, 0x4f95, 0x3c00, + 0x0024, 0x4480, 0x914c, 0x36f3, 0xd80e, 0x36f4, 0x9813, 0x36f4, 0x1811, + 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f3, 0x5801, 0x3405, + 0x9014, 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x2814, 0x9c91, + 0x0000, 0x004d, 0x2814, 0x9940, 0x003f, 0x0013, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3655, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb810, 0x3e13, + 0xf80e, 0x3e03, 0x534c, 0x3450, 0x4024, 0x6814, 0x0024, 0x0000, 0x0024, + 0x2800, 0x7618, 0x4192, 0x0024, 0x2400, 0x75c1, 0x0000, 0x0024, 0xf400, + 0x4450, 0x2938, 0x1880, 0x3613, 0x0024, 0x3c10, 0x050c, 0x3c10, 0x4024, + 0x3c90, 0x8024, 0x34f3, 0x0024, 0x3464, 0x0024, 0x3011, 0x0c40, 0x3011, + 0x4c41, 0x2915, 0x9900, 0x3011, 0x8f82, 0x3411, 0x2c40, 0x3411, 0x6c41, + 0x2915, 0xa580, 0x34e1, 0xaf82, 0x3009, 0x3040, 0x4c8a, 0x0040, 0x3010, + 0x7041, 0x2800, 0x6854, 0x3010, 0xb382, 0x3411, 0x0024, 0x3411, 0x6c44, + 0x34e1, 0xac45, 0xbe8a, 0xaf86, 0x0fe0, 0x0006, 0x3009, 0x3044, 0x3009, + 0x3045, 0x3009, 0x3386, 0x3411, 0x0024, 0x3411, 0x4ccc, 0x2915, 0x9900, + 0x34e1, 0x984c, 0x3e10, 0x7800, 0x3009, 0x3802, 0x3011, 0x0c40, 0x3011, + 0x4c41, 0x2915, 0x9900, 0x30e1, 0x8f82, 0x3009, 0x1bc6, 0x2915, 0xa940, + 0x36f1, 0x5804, 0x3011, 0x2c40, 0x3011, 0x6c41, 0x30b1, 0xac42, 0x3009, + 0x0c40, 0x3009, 0x0c41, 0x2915, 0x9900, 0x3613, 0x0f82, 0x3e10, 0x7800, + 0x3009, 0x3802, 0x3010, 0x1044, 0x3010, 0x5045, 0x2915, 0x9900, 0x3010, + 0x9386, 0x3009, 0x1bc6, 0x2915, 0xa940, 0x36f1, 0x5804, 0xf1ca, 0xac40, + 0x4ce2, 0xac41, 0x3009, 0x2ec2, 0x2800, 0x7112, 0x629c, 0x0024, 0xf1c2, + 0x4182, 0x3c10, 0x0c44, 0x3c10, 0x4c45, 0x2915, 0x4780, 0x3ce0, 0x8f86, + 0x4080, 0x0024, 0x0000, 0x0024, 0x2800, 0x75d5, 0x0020, 0x0000, 0x3411, + 0x0c40, 0x3411, 0x4c41, 0x2915, 0xb780, 0x34e1, 0x8f82, 0x0000, 0x03c3, + 0x4234, 0x0024, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2915, 0x4355, 0x0000, + 0x75c8, 0x0000, 0x0000, 0x3a10, 0x0d8c, 0x36f3, 0x538c, 0x36f3, 0xd80e, + 0x36f1, 0x9810, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, + 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, + 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3645, + 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, + 0x3e11, 0xb810, 0x3e13, 0xf80e, 0x3e03, 0x534c, 0x3440, 0x4024, 0x4192, + 0x0024, 0x2400, 0x91c1, 0x0000, 0x0024, 0xb68c, 0x4450, 0x2938, 0x1880, + 0x3613, 0x050c, 0x3c10, 0x0c40, 0x3c10, 0x4c41, 0x3ce0, 0x8f82, 0x003c, + 0x2584, 0x2915, 0x9900, 0x0018, 0x8245, 0x3411, 0x2c40, 0x3411, 0x6c41, + 0x2915, 0xa580, 0x34e1, 0xac42, 0x4c8a, 0xb040, 0x3009, 0x3041, 0x2800, + 0x82d4, 0x3009, 0x3382, 0x3411, 0x0f4c, 0x3411, 0x6c44, 0x34e1, 0xac45, + 0xbe8a, 0xac46, 0x499c, 0xb044, 0xf38c, 0xb045, 0x3009, 0x3386, 0x3009, + 0x0c40, 0x3009, 0x0c41, 0xf1ca, 0x8f82, 0x4ce2, 0x1044, 0x3411, 0x4024, + 0x2800, 0x8512, 0x4294, 0x1386, 0x6294, 0x0024, 0xf1c2, 0x0024, 0x4e8a, + 0x4195, 0x35e3, 0x0024, 0x2915, 0xa955, 0xf400, 0x4546, 0x3009, 0x2c40, + 0x3009, 0x2c41, 0x3009, 0x2c42, 0x3009, 0x0c40, 0x3009, 0x0c41, 0xf1ca, + 0x8f82, 0x4ce2, 0x9044, 0x3009, 0x1045, 0x2800, 0x8985, 0x3009, 0x1386, + 0x2800, 0x8992, 0x4294, 0x0024, 0x6294, 0x0024, 0xf1c2, 0x0024, 0x4e8a, + 0x4195, 0x35e3, 0x0024, 0x2915, 0xa955, 0xf400, 0x4546, 0xf1ca, 0xac40, + 0x4ce2, 0xac41, 0x3009, 0x2ec2, 0x2800, 0x8c12, 0x629c, 0x0024, 0xf1c2, + 0x4182, 0x3c20, 0x0c84, 0x3cf0, 0x8fc6, 0x6264, 0x4017, 0x3cf0, 0x4fc5, + 0x2800, 0x91c8, 0x0020, 0x0000, 0x2800, 0x8f19, 0xf400, 0x45c0, 0x6cea, + 0x0024, 0x0000, 0x0024, 0x2800, 0x91c9, 0x0020, 0x0000, 0x3411, 0x0c40, + 0x3411, 0x4c41, 0x2915, 0xb780, 0x34e1, 0x8f82, 0x0000, 0x03c3, 0x4234, + 0x0024, 0x4c82, 0x0024, 0x0000, 0x0024, 0x2915, 0x4355, 0x0000, 0x91c8, + 0x0000, 0x0000, 0x3a10, 0x0d8c, 0x36f3, 0x53cc, 0x36f3, 0xd80e, 0x36f1, + 0x9810, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0xf400, + 0x4595, 0x35e3, 0x3840, 0x3e13, 0xf80e, 0x3e13, 0x7808, 0x3510, 0x0024, + 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e00, + 0x0024, 0x0001, 0xce8e, 0x002b, 0xb30f, 0x292d, 0xa940, 0x0000, 0x004d, + 0x36d3, 0x0024, 0x36f3, 0x5808, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x3009, + 0x1800, 0xf400, 0x4595, 0x35f3, 0x3840, 0x3e13, 0xf80e, 0x3e13, 0x7808, + 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e00, 0x0024, 0x0000, + 0x9dce, 0x0028, 0x088f, 0x2927, 0xff80, 0x0000, 0x008d, 0x36e3, 0x0024, + 0x36f3, 0x5808, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x3009, 0x1800, 0x0028, + 0x2b0f, 0x0000, 0xa34e, 0x2828, 0x0b15, 0x0007, 0x2605, 0x3613, 0x0001, + 0x3e14, 0x3811, 0x0001, 0x0011, 0x0001, 0xcc10, 0x2915, 0x94c0, 0x0000, + 0x4000, 0x3e10, 0x534c, 0x3430, 0xc024, 0x3e10, 0xc024, 0x2927, 0xc4c0, + 0x3e01, 0x0024, 0x36d3, 0x0024, 0x0001, 0x0011, 0x0001, 0xcc10, 0x2915, + 0x94c0, 0x0000, 0x4000, 0x2828, 0x0b00, 0x36f4, 0x1811, 0x3e00, 0x0024, + 0x2800, 0xa740, 0x0028, 0x2bc8, 0x3605, 0x7840, 0x3e13, 0x780e, 0x3e13, + 0xf808, 0x3e05, 0x4024, 0x0000, 0x458e, 0x0027, 0x9e0f, 0x2922, 0xa6c0, + 0x0000, 0x190d, 0x36f3, 0x0024, 0x36f3, 0xd808, 0x36f3, 0x580e, 0x2000, + 0x0000, 0x3009, 0x1800, 0xf400, 0x4595, 0x35d3, 0x3840, 0x3e13, 0xf80e, + 0x3e13, 0x7808, 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e10, + 0x0024, 0x3510, 0x0024, 0x3e10, 0x0024, 0x3510, 0x0024, 0x3e00, 0x0024, + 0x0000, 0xac8e, 0x0025, 0xf54f, 0x2925, 0xe580, 0x0000, 0x004d, 0x36c3, + 0x0024, 0x36f3, 0x5808, 0x36f3, 0xd80e, 0x2000, 0x0000, 0x3009, 0x1800, + 0x3433, 0x0000, 0x6890, 0x3040, 0x3cc0, 0xa000, 0x0008, 0x6201, 0x000d, + 0x3500, 0x3613, 0x110c, 0x3e10, 0x0024, 0x3e10, 0x4024, 0x34c0, 0x8024, + 0x2900, 0x94c0, 0x3e00, 0x8024, 0x0026, 0x0a4f, 0x0000, 0xb04e, 0x2825, + 0xf880, 0x0000, 0x07cd, 0x0000, 0x0801, 0x6012, 0x0024, 0x0000, 0x0024, + 0x2826, 0x0a85, 0x0000, 0x0024, 0x2800, 0xad40, 0x0000, 0x0024, 0x3605, + 0x7840, 0x3e13, 0x780e, 0x3e13, 0xf808, 0x3e05, 0x4024, 0x0000, 0xb54e, + 0x0022, 0xf54f, 0x2922, 0xda80, 0x0000, 0x190d, 0x36f3, 0x0024, 0x36f3, + 0xd808, 0x36f3, 0x580e, 0x2000, 0x0000, 0x3009, 0x1800, 0x3e00, 0x0024, + 0x2800, 0x9980, 0x0022, 0xf608, 0x3605, 0x7840, 0x3e13, 0x780e, 0x3e13, + 0xf808, 0x3e05, 0x4024, 0x0000, 0xb94e, 0x0022, 0xa1cf, 0x2922, 0x9980, + 0x0000, 0x190d, 0x36f3, 0x0024, 0x36f3, 0xd808, 0x36f3, 0x580e, 0x2000, + 0x0000, 0x3009, 0x1800, 0x3009, 0x3400, 0x2800, 0xb200, 0x0022, 0xa288, + 0x2a01, 0x5a4e, 0x2a02, 0x7c0e, 0x2a02, 0x964e, 0x0007, 0x0001, /*copy 1*/ + 0x8300, 0x0006, 0x0ff6, /*copy 4086*/ + 0x0030, 0x0055, 0xb080, 0x1402, 0x0fdf, 0xffc1, 0x0007, 0x9257, 0xb212, + 0x3c00, 0x3d00, 0x4024, 0x0006, 0x0097, 0x3f10, 0x0024, 0x3f00, 0x0024, + 0x0030, 0x0297, 0x3f00, 0x0024, 0x0007, 0x9017, 0x3f00, 0x0024, 0x0007, + 0x81d7, 0x3f10, 0x0024, 0xc090, 0x3c00, 0x0006, 0x0297, 0xb080, 0x3c00, + 0x0000, 0x0401, 0x000a, 0x1055, 0x0006, 0x0017, 0x3f10, 0x3401, 0x000a, + 0x2795, 0x3f00, 0x3401, 0x0001, 0x6ad7, 0xf400, 0x55c0, 0x0000, 0x0817, + 0xb080, 0x57c0, 0x0014, 0x958f, 0x0000, 0x5b4e, 0x0030, 0x0017, 0x3700, + 0x0024, 0x0004, 0x0001, 0xb012, 0x0024, 0x0000, 0x004d, 0x280f, 0xe115, + 0x0006, 0x2016, 0x0006, 0x01d7, 0x3f00, 0x0024, 0x0000, 0x190d, 0x000f, + 0xf94f, 0x0000, 0xcd0e, 0x280f, 0xe100, 0x0006, 0x2016, 0x0000, 0x0080, + 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, 0x0006, 0x0197, 0x0006, + 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0007, 0x8a57, 0x3700, 0x0024, + 0x4080, 0x0024, 0x0000, 0x0040, 0x2800, 0xced5, 0x0006, 0xa2d7, 0x3009, + 0x3c00, 0x0006, 0xa157, 0x3009, 0x1c00, 0x0006, 0x01d7, 0x0000, 0x190d, + 0x000a, 0x708f, 0x0000, 0xd7ce, 0x290b, 0x1a80, 0x3f00, 0x184c, 0x0030, + 0x0017, 0x4080, 0x1c01, 0x0000, 0x0200, 0x2800, 0xcb15, 0xb102, 0x0024, + 0x0000, 0xcd08, 0x2800, 0xcb15, 0x0000, 0xd3ce, 0x0011, 0x210f, 0x0000, + 0x190d, 0x280f, 0xcb00, 0x3613, 0x0024, 0x0006, 0xa115, 0x0006, 0x01d7, + 0x37f0, 0x1401, 0x6100, 0x1c01, 0x4012, 0x0024, 0x0000, 0x8000, 0x6010, + 0x0024, 0x34f3, 0x0400, 0x2800, 0xd698, 0x0000, 0x0024, 0x0000, 0x8001, + 0x6010, 0x3c01, 0x0000, 0x000d, 0x2811, 0x8259, 0x0000, 0x0024, 0x2a11, + 0x2100, 0x0030, 0x0257, 0x3700, 0x0024, 0x4080, 0x0024, 0x0000, 0x0024, + 0x2800, 0xd9d5, 0x0006, 0x0197, 0x0006, 0xa115, 0x3f00, 0x3400, 0x003f, + 0xc000, 0xb600, 0x41c1, 0x0012, 0x5103, 0x000c, 0xc002, 0xdcd6, 0x0024, + 0x0019, 0xd4c2, 0x2802, 0x0c45, 0x0001, 0x1008, 0x0013, 0xd9c3, 0x6fd6, + 0x0024, 0x0000, 0x190d, 0x2800, 0xdf95, 0x0014, 0x1b01, 0x0020, 0x480f, + 0x0000, 0xde4e, 0x0000, 0x190d, 0x2820, 0x41c0, 0x0001, 0x1008, 0x0039, + 0x324f, 0x0001, 0x3ece, 0x2820, 0x4a18, 0xb882, 0x0024, 0x2a20, 0x48c0, + 0x003f, 0xfd00, 0xb700, 0x0024, 0x003f, 0xf901, 0x6010, 0x0024, 0x0000, + 0x0024, 0x280a, 0xc505, 0x0000, 0x190d, 0x0014, 0x1b01, 0x0015, 0x59c0, + 0x6fc2, 0x0024, 0x0000, 0x0024, 0x2800, 0xe9d5, 0x0000, 0x0024, 0x290c, + 0x4840, 0x3613, 0x0024, 0x290c, 0x4840, 0x4086, 0x184c, 0x0000, 0x18c2, + 0x6234, 0x0024, 0x0000, 0x1d02, 0x2800, 0xe5d5, 0x6234, 0x0024, 0x0030, + 0x0317, 0x2800, 0xe9c0, 0x3f00, 0x0024, 0x0000, 0x1d82, 0x2800, 0xe855, + 0x6234, 0x0024, 0x2912, 0x0d00, 0x4084, 0x184c, 0xf200, 0x0024, 0x6200, + 0x0024, 0x0006, 0x0017, 0x2800, 0xe540, 0xb080, 0x3c40, 0x0000, 0x0202, + 0x2800, 0xe9d5, 0xa024, 0x0024, 0xc020, 0x0024, 0x2800, 0xe540, 0x0030, + 0x02d7, 0x000a, 0x8c8f, 0x0000, 0xeb0e, 0x000c, 0x0981, 0x280a, 0x71c0, + 0x002c, 0x9d40, 0x000a, 0x708f, 0x0000, 0xd7ce, 0x280a, 0xc0d5, 0x0012, + 0x5182, 0x6fd6, 0x0024, 0x003f, 0xfd81, 0x280a, 0x8e45, 0xb710, 0x0024, + 0xb710, 0x0024, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, + 0x06d5, 0xffd2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x190d, + 0x2801, 0x06d5, 0x0030, 0x0250, 0xb880, 0x104c, 0x3cf0, 0x0024, 0x0010, + 0x5500, 0xb880, 0x23c0, 0xb882, 0x2000, 0x0007, 0x8590, 0x2914, 0xbec0, + 0x0000, 0x0440, 0x0007, 0x8b50, 0xb880, 0x0024, 0x2920, 0x0100, 0x3800, + 0x0024, 0x2920, 0x0000, 0x0006, 0x8a91, 0x0000, 0x0800, 0xb880, 0xa440, + 0x003f, 0xfd81, 0xb710, 0xa7c0, 0x003f, 0xfc01, 0x6012, 0x0024, 0x0000, + 0x0101, 0x2801, 0x1015, 0x0000, 0x0024, 0xffe2, 0x0024, 0x48b2, 0x0024, + 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, 0x1015, 0x0000, 0x0024, 0x2912, + 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, 0x0006, 0x8a90, 0x2801, 0x1015, + 0x0000, 0x01c2, 0xb886, 0x8040, 0x3613, 0x03c1, 0xbcd2, 0x0024, 0x0030, + 0x0011, 0x2800, 0xfc95, 0x003f, 0xff42, 0xb886, 0x8040, 0x3009, 0x03c1, + 0x0000, 0x0020, 0xac22, 0x0024, 0x0000, 0x0102, 0x6cd2, 0x0024, 0x3e10, + 0x0024, 0x2909, 0x8c80, 0x3e00, 0x4024, 0x36f3, 0x0024, 0x3e11, 0x8024, + 0x3e01, 0xc024, 0x2901, 0x34c0, 0x0000, 0x0201, 0xf400, 0x4512, 0x2900, + 0x0c80, 0x3213, 0x1b8c, 0x3100, 0x0024, 0xb010, 0x0024, 0x0000, 0x0024, + 0x2801, 0x1015, 0x0000, 0x0024, 0x291a, 0x8a40, 0x0000, 0x0100, 0x2920, + 0x0200, 0x3633, 0x0024, 0x2920, 0x0280, 0x0000, 0x0401, 0x408e, 0x0024, + 0x2920, 0x0280, 0x0000, 0x0401, 0x003f, 0xfd81, 0xb710, 0x4006, 0x003f, + 0xfc01, 0x6012, 0x0024, 0x0000, 0x0101, 0x2801, 0x1015, 0x0000, 0x0024, + 0xffe2, 0x0024, 0x48b2, 0x0024, 0x4190, 0x0024, 0x0000, 0x0024, 0x2801, + 0x1015, 0x0000, 0x0024, 0x2912, 0x2d80, 0x0000, 0x0780, 0x4080, 0x0024, + 0x0000, 0x01c2, 0x2800, 0xf885, 0x0006, 0x8a90, 0x2a01, 0x1000, 0x2920, + 0x0100, 0x0000, 0x0401, 0x0000, 0x0180, 0x2920, 0x0200, 0x3613, 0x0024, + 0x2920, 0x0280, 0x3613, 0x0024, 0x0000, 0x0401, 0x2920, 0x0280, 0x4084, + 0x984c, 0x0019, 0x9d01, 0x6212, 0x0024, 0x001e, 0x5c01, 0x2801, 0x0b55, + 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x0d45, 0x0000, 0x0024, 0x001b, + 0x5bc1, 0x6212, 0x0024, 0x001b, 0xdd81, 0x2801, 0x1115, 0x6012, 0x0024, + 0x0000, 0x0024, 0x2801, 0x1115, 0x0000, 0x0024, 0x0000, 0x004d, 0x000a, + 0xbf4f, 0x280a, 0xb880, 0x0001, 0x0e4e, 0x0020, 0xfb4f, 0x0000, 0x190d, + 0x0001, 0x154e, 0x2920, 0xf440, 0x3009, 0x2bc1, 0x291a, 0x8a40, 0x36e3, + 0x0024, 0x0000, 0x190d, 0x000a, 0x708f, 0x280a, 0xcac0, 0x0000, 0xd7ce, + 0x0030, 0x0017, 0x3700, 0x4024, 0x0000, 0x0200, 0xb102, 0x0024, 0x0000, + 0x00c0, 0x2801, 0x1445, 0x0005, 0x4f92, 0x2909, 0xf840, 0x3613, 0x2800, + 0x0006, 0x0197, 0x0006, 0xa115, 0xb080, 0x0024, 0x3f00, 0x3400, 0x0000, + 0x190d, 0x000a, 0x708f, 0x280a, 0xc0c0, 0x0000, 0xd7ce, 0x0000, 0x004d, + 0x0020, 0xfe0f, 0x2820, 0xfb40, 0x0001, 0x164e, 0x2801, 0x1815, 0x3009, + 0x1000, 0x6012, 0x93cc, 0x0000, 0x0024, 0x2801, 0x32c5, 0x0000, 0x0024, + 0x3413, 0x0024, 0x34b0, 0x0024, 0x4080, 0x0024, 0x0000, 0x0200, 0x2801, + 0x1b15, 0xb882, 0x0024, 0x3453, 0x0024, 0x3009, 0x13c0, 0x4080, 0x0024, + 0x0000, 0x0200, 0x2801, 0x32c5, 0x0000, 0x0024, 0xb882, 0x130c, 0x0000, + 0x004d, 0x0021, 0x058f, 0x2821, 0x0340, 0x0001, 0x1c0e, 0x2801, 0x2c55, + 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0x2c55, 0x0000, 0x0024, 0x34c3, + 0x184c, 0x3e13, 0xb80f, 0xf400, 0x4500, 0x0026, 0x9dcf, 0x0001, 0x200e, + 0x0000, 0xfa0d, 0x2926, 0x8e80, 0x3e10, 0x110c, 0x36f3, 0x0024, 0x2801, + 0x2c40, 0x36f3, 0x980f, 0x001c, 0xdd00, 0x001c, 0xd901, 0x6ec2, 0x0024, + 0x001c, 0xdd00, 0x2801, 0x2315, 0x0018, 0xdbc1, 0x3413, 0x184c, 0xf400, + 0x4500, 0x2926, 0xc640, 0x3e00, 0x13cc, 0x2801, 0x2a00, 0x36f3, 0x0024, + 0x6ec2, 0x0024, 0x003f, 0xc000, 0x2801, 0x2595, 0x002a, 0x4001, 0x3413, + 0x184c, 0xf400, 0x4500, 0x2926, 0xafc0, 0x3e00, 0x13cc, 0x2801, 0x2a00, + 0x36f3, 0x0024, 0xb400, 0x0024, 0xd100, 0x0024, 0x0000, 0x0024, 0x2801, + 0x2a05, 0x0000, 0x0024, 0x3613, 0x0024, 0x3e11, 0x4024, 0x2926, 0x8540, + 0x3e01, 0x0024, 0x4080, 0x1b8c, 0x0000, 0x0024, 0x2801, 0x2a05, 0x0000, + 0x0024, 0x3413, 0x184c, 0xf400, 0x4500, 0x2926, 0x8e80, 0x3e10, 0x13cc, + 0x36f3, 0x0024, 0x3110, 0x8024, 0x31f0, 0xc024, 0x0000, 0x4000, 0x0000, + 0x0021, 0x6d06, 0x0024, 0x3110, 0x8024, 0x2826, 0xa8c4, 0x31f0, 0xc024, + 0x2a26, 0xad00, 0x34c3, 0x184c, 0x3410, 0x8024, 0x3430, 0xc024, 0x0000, + 0x4000, 0x0000, 0x0021, 0x6d06, 0x0024, 0x0000, 0x0024, 0x2801, 0x32d4, + 0x4d06, 0x0024, 0x0000, 0x0200, 0x2922, 0x1885, 0x0001, 0x3148, 0x0000, + 0x0200, 0x3e10, 0x8024, 0x2921, 0xca80, 0x3e00, 0xc024, 0x291a, 0x8a40, + 0x0000, 0x0024, 0x2922, 0x1880, 0x36f3, 0x0024, 0x0000, 0x004d, 0x0021, + 0x0ecf, 0x2821, 0x0bc0, 0x0001, 0x324e, 0x2801, 0x1540, 0x3c30, 0x4024, + 0x0000, 0x190d, 0x0001, 0x33ce, 0x2821, 0x0f80, 0x0021, 0x420f, 0x0000, + 0x190d, 0x3e00, 0x0024, 0x2801, 0xe840, 0x0021, 0x42c8, 0x0020, 0xcd4f, + 0x2820, 0xc780, 0x0001, 0x358e, 0x0006, 0xf017, 0x0000, 0x0015, 0xb070, + 0xbc15, 0x0001, 0x374e, 0x0020, 0xdf0f, 0x2820, 0xcd80, 0x0000, 0x190d, + 0x3e00, 0x23c1, 0x2801, 0xe840, 0x0020, 0xdfc8, 0x3613, 0x0024, 0x3e10, + 0xb803, 0x3e14, 0x3811, 0x3e11, 0x3805, 0x3e00, 0x3801, 0x0007, 0xc390, + 0x0006, 0xa011, 0x3010, 0x0444, 0x3050, 0x4405, 0x6458, 0x0302, 0xff94, + 0x4081, 0x0003, 0xffc5, 0x48b6, 0x0024, 0xff82, 0x0024, 0x42b2, 0x0042, + 0xb458, 0x0003, 0x4cd6, 0x9801, 0xf248, 0x1bc0, 0xb58a, 0x0024, 0x6de6, + 0x1804, 0x0006, 0x0010, 0x3810, 0x9bc5, 0x3800, 0xc024, 0x36f4, 0x1811, + 0x36f0, 0x9803, 0x283e, 0x2d80, 0x0fff, 0xffc3, 0x2801, 0x4c80, 0x0000, + 0x0024, 0x3413, 0x0024, 0x2801, 0x4085, 0xf400, 0x4517, 0x2801, 0x4480, + 0x6894, 0x13cc, 0x37b0, 0x184c, 0x6090, 0x1d51, 0x0000, 0x0910, 0x3f00, + 0x060c, 0x3100, 0x4024, 0x6016, 0xb812, 0x000c, 0x8012, 0x2801, 0x4311, + 0xb884, 0x0024, 0x6894, 0x3002, 0x0000, 0x028d, 0x003a, 0x5e0f, 0x0001, + 0x548e, 0x2939, 0xb0c0, 0x3e10, 0x93cc, 0x4084, 0x9bd2, 0x4282, 0x0024, + 0x0000, 0x0040, 0x2801, 0x4685, 0x4292, 0x130c, 0x3443, 0x0024, 0x2801, + 0x47c5, 0x000c, 0x8390, 0x2a01, 0x4b40, 0x3444, 0x0024, 0x3073, 0x0024, + 0xc090, 0x014c, 0x2801, 0x4b40, 0x3800, 0x0024, 0x000c, 0x4113, 0xb880, + 0x2380, 0x3304, 0x4024, 0x3800, 0x05cc, 0xcc92, 0x05cc, 0x3910, 0x0024, + 0x3910, 0x4024, 0x000c, 0x8110, 0x3910, 0x0024, 0x39f0, 0x4024, 0x3810, + 0x0024, 0x38d0, 0x4024, 0x3810, 0x0024, 0x38f0, 0x4024, 0x34c3, 0x0024, + 0x3444, 0x0024, 0x3073, 0x0024, 0x3063, 0x0024, 0x3000, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, 0x4284, 0x0024, 0x3613, 0x0024, + 0x2801, 0x4e85, 0x6898, 0xb804, 0x0000, 0x0084, 0x293b, 0x1cc0, 0x3613, + 0x0024, 0x000c, 0x8117, 0x3711, 0x0024, 0x37d1, 0x4024, 0x4e8a, 0x0024, + 0x0000, 0x0015, 0x2801, 0x5145, 0xce9a, 0x0024, 0x3f11, 0x0024, 0x3f01, + 0x4024, 0x000c, 0x8197, 0x408a, 0x9bc4, 0x3f15, 0x4024, 0x2801, 0x5385, + 0x4284, 0x3c15, 0x6590, 0x0024, 0x0000, 0x0024, 0x2839, 0x53d5, 0x4284, + 0x0024, 0x0000, 0x0024, 0x2801, 0x3f58, 0x458a, 0x0024, 0x2a39, 0x53c0, + 0x003e, 0x2d4f, 0x283a, 0x5ed5, 0x0001, 0x380e, 0x000c, 0x4653, 0x0000, + 0x0246, 0xffac, 0x0c01, 0x48be, 0x0024, 0x4162, 0x4546, 0x6642, 0x4055, + 0x3501, 0x8024, 0x0000, 0x0087, 0x667c, 0x4057, 0x000c, 0x41d5, 0x283a, + 0x62d5, 0x3501, 0x8024, 0x667c, 0x1c47, 0x3701, 0x8024, 0x283a, 0x62d5, + 0xc67c, 0x0024, 0x0000, 0x0024, 0x283a, 0x62c5, 0x0000, 0x0024, 0x2a3a, + 0x5ec0, 0x3009, 0x3851, 0x3e14, 0xf812, 0x3e12, 0xb817, 0x3e11, 0x8024, + 0x0006, 0x0293, 0x3301, 0x8024, 0x468c, 0x3804, 0x0006, 0xa057, 0x2801, + 0x6084, 0x0006, 0x0011, 0x469c, 0x0024, 0x3be1, 0x8024, 0x2801, 0x6095, + 0x0006, 0xc392, 0x3311, 0x0024, 0x33f1, 0x2844, 0x3009, 0x2bc4, 0x0030, + 0x04d2, 0x3311, 0x0024, 0x3a11, 0x0024, 0x3201, 0x8024, 0x003f, 0xfc04, + 0xb64c, 0x0fc4, 0xc648, 0x0024, 0x3a01, 0x0024, 0x3111, 0x1fd3, 0x6498, + 0x07c6, 0x868c, 0x2444, 0x0023, 0xffd2, 0x3901, 0x8e06, 0x0030, 0x0551, + 0x3911, 0x8e06, 0x3961, 0x9c44, 0xf400, 0x44c6, 0xd46c, 0x1bc4, 0x36f1, + 0xbc13, 0x2801, 0x6a15, 0x36f2, 0x9817, 0x002b, 0xffd2, 0x3383, 0x188c, + 0x3e01, 0x8c06, 0x0006, 0xa097, 0x3009, 0x1c12, 0x3213, 0x0024, 0x468c, + 0xbc12, 0x002b, 0xffd2, 0xf400, 0x4197, 0x2801, 0x6704, 0x3713, 0x0024, + 0x2801, 0x6745, 0x37e3, 0x0024, 0x3009, 0x2c17, 0x3383, 0x0024, 0x3009, + 0x0c06, 0x468c, 0x4197, 0x0006, 0xa052, 0x2801, 0x6944, 0x3713, 0x2813, + 0x2801, 0x6985, 0x37e3, 0x0024, 0x3009, 0x2c17, 0x36f1, 0x8024, 0x36f2, + 0x9817, 0x36f4, 0xd812, 0x2100, 0x0000, 0x3904, 0x5bd1, 0x2a01, 0x5a4e, + 0x3e11, 0x7804, 0x0030, 0x0257, 0x3701, 0x0024, 0x0013, 0x4d05, 0xd45b, + 0xe0e1, 0x0007, 0xc795, 0x2801, 0x7195, 0x0fff, 0xff45, 0x3511, 0x184c, + 0x4488, 0xb808, 0x0006, 0x8a97, 0x2801, 0x7145, 0x3009, 0x1c40, 0x3511, + 0x1fc1, 0x0000, 0x0020, 0xac52, 0x1405, 0x6ce2, 0x0024, 0x0000, 0x0024, + 0x2801, 0x7141, 0x68c2, 0x0024, 0x291a, 0x8a40, 0x3e10, 0x0024, 0x2921, + 0xca80, 0x3e00, 0x4024, 0x36f3, 0x0024, 0x3009, 0x1bc8, 0x36f0, 0x1801, + 0x3601, 0x5804, 0x3e13, 0x780f, 0x3e13, 0xb808, 0x0008, 0x9b0f, 0x0001, + 0x744e, 0x2908, 0x9300, 0x0000, 0x004d, 0x36f3, 0x9808, 0x2000, 0x0000, + 0x36f3, 0x580f, 0x0007, 0x81d7, 0x3711, 0x8024, 0x3711, 0xc024, 0x3700, + 0x0024, 0x0000, 0x2001, 0xb012, 0x0024, 0x0034, 0x0000, 0x2801, 0x79c5, + 0x0000, 0x01c1, 0x3700, 0x0024, 0x0002, 0x0001, 0xb012, 0x0024, 0x002e, + 0xe001, 0x2801, 0x78c5, 0x6512, 0x0024, 0x0034, 0x0000, 0x2801, 0x79d5, + 0x0000, 0x01c1, 0x0030, 0x0117, 0x3f00, 0x0024, 0x0014, 0xc000, 0x0000, + 0x01c1, 0x4fce, 0x0024, 0xffea, 0x0024, 0x48b6, 0x0024, 0x4384, 0x4097, + 0xb886, 0x45c6, 0xfede, 0x0024, 0x4db6, 0x0024, 0x466c, 0x0024, 0x0006, + 0xc610, 0x8dd6, 0x8007, 0x0000, 0x00c6, 0xff6e, 0x0024, 0x48b2, 0x0024, + 0x0034, 0x2406, 0xffee, 0x0024, 0x2914, 0xaa80, 0x40b2, 0x0024, 0xf1c6, + 0x0024, 0xf1d6, 0x0024, 0x0000, 0x0201, 0x8d86, 0x0024, 0x61de, 0x0024, + 0x0006, 0xc612, 0x2801, 0x8041, 0x0006, 0xc713, 0x4c86, 0x0024, 0x2912, + 0x1180, 0x0006, 0xc351, 0x0006, 0x0210, 0x2912, 0x0d00, 0x3810, 0x984c, + 0xf200, 0x2043, 0x2808, 0xa000, 0x3800, 0x0024, 0x3e12, 0xb817, 0x3e12, + 0x7808, 0x3e11, 0xb811, 0x3e15, 0x7810, 0x3e18, 0xb823, 0x3e18, 0x3821, + 0x3e10, 0x3801, 0x48b2, 0x0024, 0x3e10, 0x3801, 0x3e11, 0x3802, 0x3009, + 0x3814, 0x0030, 0x0717, 0x3f05, 0xc024, 0x0030, 0x0351, 0x3100, 0x0024, + 0x4080, 0x0024, 0x0030, 0x10d1, 0x2801, 0x8d45, 0x0001, 0x800a, 0x0006, + 0x6514, 0x3111, 0x8024, 0x6894, 0x13c1, 0x6618, 0x0024, 0xfe44, 0x1000, + 0x4cb2, 0x0406, 0x3c10, 0x0024, 0x3c50, 0x4024, 0x34f0, 0x4024, 0x661c, + 0x1040, 0xfe64, 0x0024, 0x4cb2, 0x0024, 0x3cf0, 0x4024, 0xbc82, 0x3080, + 0x0030, 0x0351, 0x3100, 0x8024, 0xfea8, 0x0024, 0x5ca2, 0x0024, 0x0000, + 0x0182, 0xac22, 0x0024, 0xf7c8, 0x0024, 0x48b2, 0x0024, 0xac22, 0x0024, + 0x2801, 0x90c0, 0xf7cc, 0x1002, 0x0030, 0x0394, 0x3400, 0x4024, 0x3100, + 0x184c, 0x0006, 0xc051, 0x291e, 0x8080, 0x0006, 0x6410, 0x4088, 0x1001, + 0x0030, 0x1111, 0x3100, 0x184c, 0x0006, 0xc051, 0x291e, 0x8080, 0x0006, + 0x6550, 0x0006, 0x6694, 0x408c, 0x1002, 0xf224, 0x0024, 0x0006, 0xa017, + 0x2801, 0x94d5, 0x0000, 0x0024, 0x2808, 0x3f41, 0x0006, 0x6410, 0x3050, + 0x0024, 0x3000, 0x4024, 0x6014, 0x0024, 0x0000, 0x0024, 0x2801, 0x9419, + 0x0000, 0x0024, 0xf400, 0x4040, 0x38b0, 0x0024, 0x2808, 0x3f40, 0x3800, + 0x0024, 0x2801, 0x96c1, 0xf224, 0x0024, 0x0000, 0x0024, 0x2808, 0x3f45, + 0x4684, 0x4106, 0xf12c, 0x0024, 0xf148, 0x0024, 0x846c, 0x0024, 0x2808, + 0x3f40, 0xf400, 0x4184, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, + 0x3625, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, + 0x3805, 0x3e11, 0xb807, 0x3e14, 0x3811, 0x0006, 0xa090, 0x2912, 0x0d00, + 0x3e14, 0xc024, 0x4088, 0x8000, 0x4080, 0x0024, 0x0007, 0x90d1, 0x2801, + 0x9d05, 0x0000, 0x0024, 0x0007, 0x9051, 0x3100, 0x4024, 0x4100, 0x0024, + 0x3900, 0x0024, 0x0007, 0x90d1, 0x0004, 0x0000, 0x31f0, 0x4024, 0x6014, + 0x0400, 0x0000, 0x0024, 0x2801, 0xa151, 0x4080, 0x0024, 0x0000, 0x0000, + 0x2801, 0xa0c5, 0x0000, 0x0024, 0x0007, 0x9053, 0x3300, 0x0024, 0x4080, + 0x0024, 0x0000, 0x0000, 0x2801, 0xa158, 0x0000, 0x0024, 0x0007, 0x9051, + 0x3900, 0x0024, 0x3200, 0x504c, 0x6410, 0x0024, 0x3cf0, 0x0000, 0x4080, + 0x0024, 0x0006, 0xc691, 0x2801, 0xba05, 0x3009, 0x0400, 0x0007, 0x9051, + 0x0000, 0x1001, 0x3100, 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2801, + 0xae49, 0x003f, 0xe000, 0x0006, 0xc693, 0x3900, 0x0c00, 0x3009, 0x0001, + 0x6014, 0x0024, 0x0007, 0x1ad0, 0x2801, 0xae55, 0x3009, 0x0000, 0x4080, + 0x0024, 0x0000, 0x0301, 0x2801, 0xa845, 0x4090, 0x0024, 0x0000, 0x0024, + 0x2801, 0xa955, 0x0000, 0x0024, 0x3009, 0x0000, 0xc012, 0x0024, 0x2801, + 0xae40, 0x3009, 0x2001, 0x3009, 0x0000, 0x6012, 0x0024, 0x0000, 0x0341, + 0x2801, 0xab55, 0x0000, 0x0024, 0x6190, 0x0024, 0x2801, 0xae40, 0x3009, + 0x2000, 0x6012, 0x0024, 0x0000, 0x0381, 0x2801, 0xad15, 0x0000, 0x0024, + 0x6190, 0x0024, 0x2801, 0xae40, 0x3009, 0x2000, 0x6012, 0x0024, 0x0000, + 0x00c0, 0x2801, 0xae55, 0x0000, 0x0024, 0x3009, 0x2000, 0x0006, 0xa090, + 0x3009, 0x0000, 0x4080, 0x0024, 0x0000, 0x0081, 0x2801, 0xb315, 0x0007, + 0x8c13, 0x3300, 0x104c, 0xb010, 0x0024, 0x0002, 0x8001, 0x2801, 0xb585, + 0x34f0, 0x0024, 0x2801, 0xb300, 0x0000, 0x0024, 0x0006, 0xc351, 0x3009, + 0x0000, 0x6090, 0x0024, 0x3009, 0x2000, 0x2900, 0x0b80, 0x3009, 0x0405, + 0x0006, 0xc690, 0x0006, 0xc6d1, 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, + 0x0024, 0x0006, 0xa093, 0x2801, 0xb191, 0xb880, 0x0024, 0x2801, 0xc2c0, + 0x3009, 0x2c00, 0x4040, 0x0024, 0x6012, 0x0024, 0x0006, 0xc6d0, 0x2801, + 0xc2d8, 0x0000, 0x0024, 0x0006, 0xc693, 0x3009, 0x0c00, 0x3009, 0x0001, + 0x6014, 0x0024, 0x0006, 0xc350, 0x2801, 0xc2c1, 0x0000, 0x0024, 0x6090, + 0x0024, 0x3009, 0x2c00, 0x3009, 0x0005, 0x2900, 0x0b80, 0x0001, 0xc2c8, + 0x3009, 0x0400, 0x4080, 0x0024, 0x0003, 0x8000, 0x2801, 0xc2c5, 0x0000, + 0x0024, 0x6400, 0x0024, 0x0000, 0x0081, 0x2801, 0xc2c9, 0x0000, 0x0024, + 0x0007, 0x8c13, 0x3300, 0x0024, 0xb010, 0x0024, 0x0006, 0xc650, 0x2801, + 0xc2d5, 0x0000, 0x0024, 0x0001, 0x0002, 0x3413, 0x0000, 0x3009, 0x0401, + 0x4010, 0x8406, 0x0000, 0x0281, 0xa010, 0x13c1, 0x4122, 0x0024, 0x0000, + 0x03c2, 0x6122, 0x8002, 0x462c, 0x0024, 0x469c, 0x0024, 0xfee2, 0x0024, + 0x48be, 0x0024, 0x6066, 0x8400, 0x0006, 0xc350, 0x2801, 0xc2c1, 0x0000, + 0x0024, 0x4090, 0x0024, 0x3009, 0x2400, 0x2900, 0x0b80, 0x3009, 0x0005, + 0x0007, 0x1b50, 0x2912, 0x0d00, 0x3613, 0x0024, 0x3a00, 0x0380, 0x4080, + 0x0024, 0x0000, 0x00c1, 0x2801, 0xcb85, 0x3009, 0x0000, 0xb010, 0x008c, + 0x4192, 0x0024, 0x6012, 0x0024, 0x0006, 0xf051, 0x2801, 0xc998, 0x3009, + 0x0400, 0x0007, 0x1fd1, 0x30e3, 0x0400, 0x4080, 0x0024, 0x0000, 0x0301, + 0x2801, 0xcb85, 0x3009, 0x0000, 0xb010, 0x0024, 0x0000, 0x0101, 0x6012, + 0x0024, 0x0006, 0xf051, 0x2801, 0xcb95, 0x0000, 0x0024, 0x3023, 0x0400, + 0xf200, 0x184c, 0xb880, 0xa400, 0x3009, 0x2000, 0x3009, 0x0441, 0x3e10, + 0x4402, 0x2909, 0xa9c0, 0x3e10, 0x8024, 0x36e3, 0x0024, 0x36f4, 0xc024, + 0x36f4, 0x1811, 0x36f1, 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, + 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, + 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, + 0x3e11, 0x3805, 0x3e11, 0xf810, 0x0001, 0x0010, 0x3e14, 0x7812, 0xb882, + 0x3813, 0x2914, 0xbec0, 0x0000, 0x2200, 0xb886, 0x12cc, 0x2801, 0xd800, + 0x3454, 0x8024, 0x0001, 0x0000, 0x3000, 0x984c, 0x4234, 0xb843, 0xf400, + 0x4095, 0x003b, 0xffc2, 0x3500, 0x4024, 0xb122, 0x0842, 0x4010, 0x0bc3, + 0x4010, 0x0024, 0x4010, 0x0024, 0x4010, 0x0024, 0x4d82, 0x4011, 0x2938, + 0x0600, 0xf400, 0x4450, 0x3223, 0x184c, 0x3210, 0x8024, 0x32d0, 0xc024, + 0x2938, 0x0600, 0x4d82, 0x4450, 0x3243, 0x1bc3, 0x6396, 0x0024, 0x0005, + 0xdf90, 0x3000, 0x0024, 0x6302, 0x0024, 0x0005, 0xe110, 0x2801, 0xd2d1, + 0x0000, 0x0024, 0x2801, 0xde80, 0x4086, 0x0024, 0x3200, 0x930c, 0x6398, + 0x1111, 0x4244, 0x0844, 0xf400, 0x4095, 0x3500, 0x584c, 0x4438, 0x0805, + 0x453a, 0x4115, 0x3500, 0x8024, 0x6122, 0x4155, 0x4280, 0x1404, 0x0001, + 0x0002, 0x4244, 0x0024, 0x4244, 0x0024, 0x4244, 0x0024, 0x4244, 0x0024, + 0x2938, 0x2f80, 0xf400, 0x4090, 0x6396, 0x0024, 0x0005, 0xdf50, 0x3000, + 0x0024, 0x6302, 0x0024, 0x0005, 0xe0d2, 0x2801, 0xda11, 0x0000, 0x0381, + 0x3073, 0x0024, 0x3023, 0x0024, 0x3000, 0x0024, 0x6012, 0x0024, 0x0001, + 0x2212, 0x2801, 0xe395, 0x0005, 0x1453, 0x0001, 0x0011, 0x3093, 0x184c, + 0x3000, 0x4024, 0x2900, 0x78c0, 0x3e00, 0x4024, 0x2801, 0xe580, 0x36f3, + 0x0024, 0x0005, 0xe3c1, 0x0001, 0x0011, 0x3613, 0x024c, 0x3e10, 0x4024, + 0x3000, 0x8024, 0x2900, 0x5c40, 0x3e00, 0x8024, 0x36e3, 0x0024, 0x36f4, + 0xc024, 0x36f4, 0x5812, 0x36f1, 0xd810, 0x36f1, 0x1805, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x0000, + 0x00c1, 0xb880, 0xb803, 0x3e10, 0x904c, 0x3e11, 0x3806, 0x3e11, 0xf810, + 0x0006, 0xf450, 0x3e14, 0x7812, 0x3e14, 0xc024, 0x3cf0, 0x2080, 0x3009, + 0x23c0, 0x3009, 0x2380, 0x0000, 0x0640, 0x3009, 0x2000, 0x2921, 0x9440, + 0x0000, 0x00c0, 0x2921, 0xdd40, 0x3613, 0x0024, 0xf400, 0x4004, 0x0000, + 0x01c0, 0x6400, 0x0024, 0x0000, 0x00c0, 0x2802, 0x0885, 0x0000, 0x01c1, + 0x6412, 0x4100, 0x0006, 0x0581, 0x2801, 0xfe01, 0x4412, 0x0024, 0xf400, + 0x4057, 0x3702, 0x0024, 0x2000, 0x0000, 0x0000, 0x0024, 0x0006, 0xf410, + 0x0000, 0x0641, 0x3613, 0x0000, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, + 0xf3d5, 0x0000, 0x0024, 0x3009, 0x2004, 0x2900, 0xb600, 0x3e01, 0x0024, + 0x2801, 0xfe00, 0x36f3, 0x0024, 0x0006, 0xf410, 0x0000, 0x0641, 0x3613, + 0x0000, 0x6012, 0x0024, 0x0000, 0x0024, 0x2801, 0xf6d5, 0x0000, 0x0024, + 0x3009, 0x2004, 0x2900, 0xa400, 0x3e01, 0x0024, 0x2801, 0xfe00, 0x36f3, + 0x0024, 0x0006, 0xf450, 0x3613, 0x0000, 0x6090, 0x3804, 0x2900, 0xb600, + 0x3009, 0x2000, 0x2801, 0xfe00, 0x36f3, 0x0024, 0x2923, 0x4f00, 0x0007, + 0x2050, 0x2801, 0xfe00, 0x3009, 0x2000, 0x2923, 0x7580, 0x0001, 0xfe08, + 0x34d3, 0x184c, 0x3430, 0x0024, 0x2922, 0x4fc0, 0x3e00, 0x0024, 0x2801, + 0xfe00, 0x36f3, 0x0024, 0x0000, 0x3fc0, 0x0007, 0x2050, 0x3613, 0x0024, + 0x2923, 0x8480, 0x3e00, 0x0024, 0x36f3, 0x2000, 0x0000, 0x1800, 0x3413, + 0x0024, 0xf400, 0x4510, 0x34f0, 0x4024, 0x6192, 0x0024, 0x6014, 0x2001, + 0x0007, 0x2051, 0x2802, 0x0081, 0x0000, 0x0280, 0x3009, 0x2400, 0x3009, + 0x0400, 0x4080, 0x0024, 0x0006, 0xf352, 0x2802, 0x0995, 0x3009, 0x0842, + 0x3009, 0x0bc3, 0x4d86, 0x0024, 0x0000, 0x0201, 0x2802, 0x04c5, 0x0030, + 0x0013, 0x0006, 0x8a93, 0x3009, 0x0c40, 0x3009, 0x0fc1, 0x6cde, 0x0024, + 0x0000, 0x0201, 0x2802, 0x0981, 0x0030, 0x0013, 0x3300, 0x0024, 0xb010, + 0x0024, 0x0000, 0x0100, 0x2802, 0x0995, 0x0000, 0x00c1, 0x2921, 0x9440, + 0x3613, 0x0024, 0x2921, 0xdd40, 0x3613, 0x0024, 0xf400, 0x4004, 0x0000, + 0x01c0, 0x6400, 0x0024, 0x0000, 0x01c1, 0x2801, 0xefd5, 0x0000, 0x00c0, + 0x2921, 0x9440, 0x3613, 0x0024, 0x2921, 0xc300, 0x0000, 0x0024, 0x36f4, + 0xc024, 0x36f4, 0x5812, 0x36f1, 0xd810, 0x36f1, 0x1806, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x0012, + 0x5103, 0x3e11, 0x3805, 0x3e11, 0xb807, 0x3e14, 0x380d, 0x0030, 0x0250, + 0x3e13, 0xf80e, 0xbe8b, 0x83e0, 0x290c, 0x4840, 0x3613, 0x0024, 0x290c, + 0x4840, 0x4086, 0x984c, 0x0000, 0x00ce, 0x2402, 0x138e, 0x3009, 0x1bc0, + 0x0000, 0x01c3, 0xae3a, 0x184c, 0x0000, 0x0043, 0x3009, 0x3842, 0x290c, + 0x4840, 0x3009, 0x3840, 0x4084, 0x9bc0, 0xfe26, 0x9bc2, 0xceba, 0x0024, + 0x4e8e, 0x0024, 0x4e9a, 0x0024, 0x4f8e, 0x0024, 0x0000, 0x0102, 0x2802, + 0x18c5, 0x0030, 0x0010, 0x0000, 0x0206, 0x3613, 0x0024, 0x290c, 0x4840, + 0x3009, 0x3840, 0x3000, 0xdbc0, 0xb366, 0x0024, 0x0000, 0x0024, 0x2802, + 0x18d5, 0x4e8e, 0x0024, 0x4e9a, 0x0024, 0x4f8e, 0x0024, 0x0030, 0x0010, + 0x2802, 0x1595, 0x0000, 0x0206, 0x36f3, 0xd80e, 0x36f4, 0x180d, 0x36f1, + 0x9807, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x3405, 0x9014, 0x36f3, 0x0024, + 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, + 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, 0x3635, 0x0024, 0x0000, 0x800a, + 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, 0x3805, 0x3e11, 0xb810, 0x3e04, + 0x7812, 0x34d3, 0x0024, 0x3400, 0x0024, 0xf200, 0x1102, 0xf200, 0x0024, + 0xf200, 0x0024, 0x3cf0, 0x0024, 0x2914, 0xba00, 0x0000, 0x1600, 0x0000, + 0x4001, 0x6012, 0x108c, 0x3ce0, 0x0024, 0x2802, 0x2209, 0x0000, 0x0386, + 0x0000, 0x4000, 0x3423, 0x0024, 0x3ce0, 0x0024, 0x0000, 0x0041, 0x3413, + 0x0024, 0x34b0, 0x8024, 0xfe22, 0x1100, 0x48b6, 0x0024, 0xad66, 0x0024, + 0xfe02, 0x0024, 0x2915, 0x8600, 0x48b2, 0x0024, 0x4c8a, 0x104c, 0x0000, + 0x0041, 0x34f0, 0x0024, 0xfe02, 0x0024, 0x0000, 0xf001, 0x6eba, 0x0024, + 0xf040, 0x0024, 0x6012, 0x0024, 0x0000, 0x0041, 0x2802, 0x2a08, 0x0000, + 0xf002, 0xf040, 0x104c, 0x3400, 0xc024, 0xfe26, 0x0024, 0x48b6, 0x0024, + 0xfe02, 0x0024, 0x2915, 0x8600, 0x48b2, 0x0024, 0x4480, 0x33c0, 0x0000, + 0xf004, 0x2802, 0x2a18, 0x0000, 0x0024, 0x003f, 0x1004, 0x0006, 0x0090, + 0x0000, 0x0041, 0xb884, 0x108c, 0x6896, 0xa004, 0x34e0, 0x0024, 0xfe02, + 0x0024, 0x2914, 0xa580, 0x48b2, 0x0024, 0x0006, 0x0110, 0x3423, 0x23c0, + 0x34f0, 0x0024, 0x3410, 0x2380, 0xb880, 0xa140, 0x3009, 0x23c0, 0x3009, + 0x2340, 0x3009, 0x0000, 0x4080, 0x0024, 0x0000, 0xba11, 0x2802, 0x2f95, + 0x0000, 0x0024, 0x2802, 0x3780, 0x3ce4, 0x4024, 0x4080, 0x138c, 0x0000, + 0x0001, 0x2802, 0x3418, 0x0006, 0x0011, 0x0000, 0xba00, 0x6090, 0x108c, + 0x3ce0, 0x0400, 0x6014, 0x0024, 0x0006, 0xa052, 0x2802, 0x3351, 0x0004, + 0x0001, 0x6014, 0x0024, 0x0000, 0x0024, 0x2802, 0x3791, 0x0000, 0x0024, + 0x3009, 0x0800, 0x2802, 0x3780, 0x3009, 0x2400, 0x0000, 0xba00, 0x6090, + 0x108c, 0x6090, 0x0024, 0x3ce0, 0x0400, 0x6014, 0x0024, 0x0006, 0xa052, + 0x2802, 0x3711, 0x0004, 0x0001, 0x6014, 0x0024, 0x0000, 0x0024, 0x2802, + 0x3791, 0x0000, 0x0024, 0x3009, 0x0800, 0x3009, 0x2400, 0x3613, 0x108c, + 0x290f, 0xfdc0, 0x34e4, 0x3810, 0x0000, 0x0810, 0x290f, 0xfcc0, 0x3009, + 0x1bcc, 0x36f4, 0x5812, 0x36f1, 0x9810, 0x36f1, 0x1805, 0x36f0, 0x9803, + 0x36f0, 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, + 0x0000, 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, + 0x3e05, 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, + 0xb803, 0x3e11, 0x3805, 0x3e14, 0x3811, 0x0006, 0x01d1, 0x0006, 0xc610, + 0x3e04, 0xb813, 0x3009, 0x0000, 0x3009, 0x0401, 0x6014, 0x0024, 0x0030, + 0x0312, 0x2802, 0x4355, 0x0000, 0x0024, 0x3200, 0x044c, 0x3009, 0x0401, + 0x6014, 0x0024, 0x0006, 0x0292, 0x2802, 0x4355, 0x0006, 0xc351, 0x3009, + 0x0400, 0x3009, 0x0801, 0x6014, 0x0024, 0x0000, 0x0024, 0x2802, 0x5985, + 0x0000, 0x0024, 0x0030, 0x0311, 0x3100, 0x0024, 0x4080, 0x0024, 0x0010, + 0x0000, 0x2802, 0x4515, 0x0000, 0x0024, 0x3900, 0x0024, 0x3100, 0x0024, + 0x4080, 0x0024, 0x0001, 0xffc0, 0x2802, 0x4b98, 0x0030, 0x00d2, 0x3201, + 0x0024, 0xb408, 0x0024, 0x0006, 0x01d3, 0x2802, 0x47d5, 0x0001, 0xf400, + 0x0001, 0x0c04, 0x4408, 0x0401, 0x3613, 0x2004, 0x0006, 0xc350, 0x6810, + 0xac44, 0x3009, 0x2c81, 0x3e10, 0x0000, 0x2902, 0x1b40, 0x3e00, 0x2c00, + 0x36f3, 0x0000, 0x6090, 0x0024, 0x3009, 0x2000, 0x3009, 0x0005, 0x459a, + 0x0024, 0x2908, 0x9300, 0x0002, 0x5988, 0x3201, 0x0024, 0xb408, 0x0024, + 0x0000, 0x0081, 0x2802, 0x4d15, 0x0006, 0x02d3, 0x0001, 0x0c04, 0x0001, + 0xf400, 0x4408, 0x8c00, 0x6012, 0x044c, 0x3009, 0x184c, 0x2802, 0x4ed5, + 0x0004, 0x0003, 0x4448, 0x0024, 0x39f0, 0x3800, 0xb884, 0x3801, 0x0000, + 0x0041, 0x3100, 0x0024, 0xfe02, 0x0024, 0x2915, 0x8600, 0x48b2, 0x0024, + 0x0006, 0x01d0, 0x0006, 0x02d1, 0xffc0, 0x1bcc, 0x48b2, 0x0024, 0x4cc2, + 0x0024, 0x4cc2, 0x0024, 0x3009, 0x2001, 0x0000, 0x0081, 0x3009, 0x0400, + 0x6012, 0x0024, 0x0006, 0xc353, 0x2802, 0x5595, 0x0030, 0x0312, 0x3200, + 0x404c, 0x3613, 0x2001, 0x3e10, 0x4c01, 0xf212, 0x0024, 0x3e00, 0x4024, + 0x2902, 0x1b40, 0x0002, 0x56c8, 0x3200, 0x404c, 0x3613, 0x2001, 0x3e10, + 0x4c01, 0x2902, 0x1b40, 0x3e00, 0x4024, 0x3023, 0x0c00, 0x36f3, 0x2340, + 0x3009, 0x0000, 0x0006, 0xc610, 0x3009, 0x2000, 0x3009, 0x0c00, 0x6090, + 0x0024, 0x3009, 0x2c00, 0x3009, 0x0c05, 0x2908, 0x9300, 0x459a, 0x0024, + 0x36f4, 0x9813, 0x36f4, 0x1811, 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, + 0x1801, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, + 0x36f2, 0x9817, 0x3613, 0x0024, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, + 0xb814, 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0xb803, 0x3e11, 0x3811, + 0x3e14, 0xb813, 0x3e13, 0xf80e, 0x2902, 0x3b80, 0x3e03, 0x4024, 0x4194, + 0x0024, 0x002b, 0x1103, 0x2802, 0x7355, 0x0006, 0xc351, 0x3009, 0x0402, + 0x6236, 0x0024, 0x0010, 0x0003, 0x2802, 0x7351, 0x0030, 0x0311, 0x3100, + 0x8024, 0x6236, 0x0024, 0x0000, 0x0024, 0x2802, 0x7105, 0x0000, 0x0024, + 0x3100, 0x8024, 0x4284, 0x0024, 0x0006, 0x0793, 0x2802, 0x7109, 0x0000, + 0x0024, 0xf100, 0x0012, 0xb888, 0x4491, 0x3300, 0x8024, 0x0006, 0x0753, + 0x6404, 0x2c02, 0x0000, 0x0024, 0x2802, 0x6818, 0x4094, 0x0024, 0x2402, + 0x6782, 0x3613, 0x0024, 0x3220, 0x3840, 0x2902, 0xafc0, 0x32e0, 0x7801, + 0x3243, 0x1bc1, 0x6498, 0x0024, 0x3920, 0x1800, 0x36f3, 0x0024, 0x0006, + 0x0753, 0xb888, 0x0c02, 0x0006, 0x0793, 0x3b10, 0x8024, 0x3004, 0x8024, + 0x3300, 0x884c, 0x0006, 0x0753, 0x6404, 0x2c02, 0x0000, 0x0024, 0x2802, + 0x6d18, 0x4094, 0x4491, 0x2402, 0x6c82, 0x3613, 0x0024, 0x3220, 0x3840, + 0x2902, 0xafc0, 0x32e0, 0x7801, 0x3243, 0x1bc1, 0x6498, 0x0024, 0x3920, + 0x1800, 0x36f3, 0x0024, 0x0006, 0x0753, 0x0000, 0x0083, 0x3300, 0x984c, + 0x0006, 0x07d3, 0x3b00, 0x8024, 0x0006, 0x02d3, 0x3009, 0x0c02, 0x6236, + 0x0024, 0x0000, 0x0082, 0x2802, 0x7085, 0x0000, 0x0024, 0xb884, 0xac02, + 0x0006, 0x0293, 0x3009, 0x2c02, 0x2802, 0x7340, 0x3009, 0x1bcc, 0x0006, + 0x02d2, 0x3613, 0x0802, 0x4294, 0x0024, 0x0006, 0x0293, 0x2802, 0x7305, + 0x6894, 0x0024, 0xb884, 0xa802, 0x3009, 0x2c02, 0x3009, 0x1bcc, 0x36f3, + 0x4024, 0x36f3, 0xd80e, 0x36f4, 0x9813, 0x36f1, 0x1811, 0x36f0, 0x9803, + 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, + 0x9817, 0x3613, 0x0024, 0x3e22, 0xb815, 0x3e05, 0xb814, 0xb880, 0x1854, + 0x3e10, 0xb811, 0x0007, 0x9251, 0xb884, 0x3812, 0x0006, 0x0792, 0x3900, + 0xb813, 0x0006, 0x0753, 0x0006, 0x1002, 0x0002, 0x5c11, 0x3a10, 0x8024, + 0x0006, 0x8002, 0x3a00, 0x8024, 0x0006, 0x1002, 0x0007, 0x9252, 0x3b00, + 0x9813, 0x3a04, 0x4024, 0x36f4, 0x8024, 0x36f0, 0x9811, 0x3405, 0x9014, + 0x36e3, 0x0024, 0x2000, 0x0000, 0x36f2, 0x9815, 0x3009, 0x3857, 0x3e18, + 0x3822, 0x3e18, 0x780a, 0x3e10, 0x3801, 0x48b2, 0x3855, 0x3e10, 0x3801, + 0x0000, 0x800a, 0x3e14, 0x3811, 0x3e14, 0xb813, 0x0006, 0x0013, 0x0023, + 0xffd1, 0x0006, 0x0192, 0x3009, 0x0800, 0x4080, 0x8c10, 0x0030, 0x0552, + 0x2802, 0x8bc5, 0xf400, 0x4401, 0x0006, 0x0093, 0x3e10, 0xb803, 0x3e01, + 0x0c40, 0x4000, 0x8cc4, 0x4010, 0x8c02, 0x0000, 0x0001, 0x6010, 0x4012, + 0x0006, 0x0113, 0x2802, 0x8398, 0x6428, 0x8c80, 0x0004, 0x0013, 0x3283, + 0x0024, 0x0006, 0x0193, 0x3009, 0x0203, 0x3009, 0x0c02, 0xfe26, 0x0024, + 0x48b6, 0x8841, 0xfe42, 0x0024, 0x4db6, 0x0024, 0xffb0, 0x4003, 0x48b2, + 0x0024, 0xffa6, 0x8203, 0x40b2, 0x8f82, 0x0030, 0x0555, 0x3d10, 0x4c80, + 0xfe26, 0x0024, 0x48b6, 0x8bc1, 0xfe42, 0x0024, 0x4db6, 0x0024, 0xffb0, + 0x4003, 0x48b2, 0x0024, 0xffa6, 0x1bc4, 0x40b2, 0x8c02, 0x4290, 0x3401, + 0x3009, 0x2f00, 0x2802, 0x8c95, 0x3009, 0x0c00, 0x4000, 0x4401, 0x4100, + 0x0024, 0x0000, 0x0001, 0x6014, 0x4010, 0x0004, 0x0001, 0x2802, 0x8c98, + 0x4010, 0x0024, 0x2802, 0x8c80, 0xf400, 0x4010, 0x3e00, 0x8200, 0x3a10, + 0x0200, 0x3a00, 0x3803, 0x0006, 0x0152, 0x6104, 0x8b00, 0x6090, 0x8901, + 0x6014, 0xa800, 0x0006, 0xa053, 0x2802, 0x8f48, 0xb880, 0x4402, 0x3009, + 0x2b80, 0x3009, 0x08c0, 0x4090, 0x4402, 0x3009, 0x2800, 0x0006, 0x0012, + 0x3009, 0x2810, 0x3009, 0x0c01, 0x6214, 0x0024, 0x0006, 0x0092, 0x2802, + 0x9198, 0x0000, 0x0100, 0x0004, 0x0001, 0x4214, 0x0024, 0x3009, 0x0801, + 0x4112, 0x8c10, 0x6010, 0x020c, 0x6204, 0x020c, 0x3083, 0x1803, 0x2802, + 0x9389, 0x36f0, 0x820c, 0x3009, 0x2c10, 0x36f4, 0x9813, 0x36f4, 0x1811, + 0x36f0, 0x1801, 0x2210, 0x0000, 0x36f5, 0x4024, 0x36f0, 0x1801, 0x36f8, + 0x580a, 0x36f8, 0x1822, 0x0030, 0x0717, 0x2100, 0x0000, 0x3f05, 0xdbd7, + 0x3009, 0x3853, 0x3e18, 0x3823, 0x3e18, 0x780a, 0x3e10, 0x3801, 0x48b2, + 0x0024, 0x3e10, 0x3801, 0x0000, 0x800a, 0x3e10, 0xb803, 0x3e11, 0x3810, + 0x3e04, 0x7812, 0x0006, 0x0010, 0x0006, 0x0191, 0x3009, 0x0400, 0x4080, + 0x8012, 0x0030, 0x0553, 0x2802, 0xa385, 0x3009, 0x0840, 0x0006, 0x0093, + 0x32f3, 0x0c40, 0x4000, 0x4481, 0x4010, 0x8843, 0xf400, 0x4011, 0x0004, + 0x0001, 0x6014, 0x8cc4, 0x0030, 0x0550, 0x2802, 0x9dd1, 0x3009, 0x0f82, + 0x0ffc, 0x0010, 0x3183, 0x0024, 0x0030, 0x0550, 0x6428, 0x184c, 0xfe27, + 0xe6e7, 0x48b6, 0x8447, 0xfe4e, 0x8c87, 0x4db6, 0x0024, 0xffbe, 0x8bc3, + 0x48b2, 0x0024, 0xffae, 0x8f82, 0x40b2, 0x0024, 0xfe26, 0x2041, 0x48b6, + 0x87c7, 0xfe4e, 0x0024, 0x4db6, 0x8c87, 0xffbe, 0x0024, 0x48b2, 0x0024, + 0xffae, 0x0024, 0x40b2, 0x8c02, 0x4290, 0x2001, 0x3009, 0x2c00, 0x2802, + 0xa415, 0x36f1, 0x9807, 0x2802, 0xa400, 0xf400, 0x4452, 0x3b10, 0x0bc0, + 0x3b00, 0x0024, 0x0006, 0x0150, 0x3223, 0x0300, 0x6090, 0x8101, 0x6014, + 0x4484, 0x0004, 0x0001, 0x2802, 0xa708, 0x6414, 0xa300, 0xb880, 0x810c, + 0x3009, 0x2380, 0x3009, 0x00c0, 0x4090, 0x4484, 0x6414, 0xa000, 0x0006, + 0xa051, 0x2802, 0xa891, 0x0006, 0x0010, 0x0ffc, 0x0013, 0x3283, 0x0024, + 0xf400, 0x4484, 0x3009, 0x0400, 0x6408, 0xa012, 0x0000, 0x0400, 0x2802, + 0xaa98, 0x6404, 0x8412, 0x0004, 0x0002, 0x4428, 0x0024, 0x6404, 0x0024, + 0x0000, 0x0413, 0x2802, 0xad08, 0x3283, 0x0024, 0xf400, 0x4480, 0x6014, + 0x0024, 0x0ffc, 0x0013, 0x2802, 0xacd1, 0x0000, 0x0024, 0x3283, 0x0024, + 0x3009, 0x2412, 0x36f4, 0x5812, 0x36f1, 0x1810, 0x36f0, 0x9803, 0x36f0, + 0x1801, 0x2210, 0x0000, 0x36f0, 0x1801, 0x36f8, 0x580a, 0x36f8, 0x1823, + 0x0030, 0x0713, 0x2100, 0x0000, 0x3b04, 0xdbd3, 0x3613, 0x0024, 0x3e12, + 0x8024, 0x3e10, 0xb803, 0x3e14, 0x3811, 0x3e14, 0xb813, 0x3e13, 0x780e, + 0x3e03, 0xc024, 0x0001, 0x000a, 0x0006, 0x0755, 0x3504, 0x0024, 0x0020, + 0x0b91, 0x3880, 0x0024, 0x3880, 0x4024, 0xbd86, 0x3410, 0x0008, 0x2b91, + 0x003f, 0x15d2, 0x0000, 0x0053, 0x0000, 0x058e, 0x2402, 0xb4ce, 0xfe25, + 0x0829, 0x5017, 0x0829, 0x000e, 0x7b91, 0x5016, 0x020c, 0x4db6, 0x0001, + 0x4d16, 0x1bcf, 0xf1d6, 0x980e, 0xf7d0, 0x1bcd, 0x36f4, 0x9813, 0x36f4, + 0x1811, 0x36f0, 0x9803, 0x2000, 0x0000, 0x36f2, 0x8024, 0xb386, 0x40d7, + 0x4284, 0x184c, 0x0000, 0x05c0, 0x2802, 0xb955, 0xf5d8, 0x3804, 0x0000, + 0x0984, 0x6400, 0xb84a, 0x3e13, 0xf80d, 0xa204, 0x380e, 0x0000, 0x800a, + 0x0000, 0x00ce, 0x2402, 0xbc8e, 0xffa4, 0x0024, 0x48b6, 0x0024, 0x0000, + 0x0024, 0x2802, 0xbc84, 0x4000, 0x40c2, 0x4224, 0x0024, 0x6090, 0x0024, + 0xffa4, 0x0024, 0x0fff, 0xfe83, 0xfe86, 0x1bce, 0x36f3, 0xd80d, 0x48b6, + 0x0024, 0x0fff, 0xff03, 0xa230, 0x45c3, 0x2000, 0x0000, 0x36f1, 0x180a, + 0x0007, 0x0001, /*copy 1*/ + 0x802e, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x6b00, 0x0007, 0x0001, /*copy 1*/ + 0x8030, 0x0006, 0x0002, /*copy 2*/ + 0x2800, 0x1b40, 0x0007, 0x0001, /*copy 1*/ + 0x8028, 0x0006, 0x0002, /*copy 2*/ + 0x2a00, 0x148e, 0x0007, 0x0001, /*copy 1*/ + 0x8032, 0x0006, 0x0002, /*copy 2*/ + 0x2801, 0x9740, 0x0007, 0x0001, /*copy 1*/ + 0x3580, 0x0006, 0x8038, 0x0000, /*Rle(56)*/ + 0x0007, 0x0001, /*copy 1*/ + 0xfab3, 0x0006, 0x01bc, /*copy 444*/ + 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0xffff, 0xfffe, 0xfffb, 0xfff9, + 0xfff5, 0xfff2, 0xffed, 0xffe8, 0xffe3, 0xffde, 0xffd8, 0xffd3, 0xffce, + 0xffca, 0xffc7, 0xffc4, 0xffc4, 0xffc5, 0xffc7, 0xffcc, 0xffd3, 0xffdc, + 0xffe6, 0xfff3, 0x0001, 0x0010, 0x001f, 0x002f, 0x003f, 0x004e, 0x005b, + 0x0066, 0x006f, 0x0074, 0x0075, 0x0072, 0x006b, 0x005f, 0x004f, 0x003c, + 0x0024, 0x0009, 0xffed, 0xffcf, 0xffb0, 0xff93, 0xff77, 0xff5f, 0xff4c, + 0xff3d, 0xff35, 0xff34, 0xff3b, 0xff4a, 0xff60, 0xff7e, 0xffa2, 0xffcd, + 0xfffc, 0x002e, 0x0061, 0x0094, 0x00c4, 0x00f0, 0x0114, 0x0131, 0x0144, + 0x014b, 0x0146, 0x0134, 0x0116, 0x00eb, 0x00b5, 0x0075, 0x002c, 0xffde, + 0xff8e, 0xff3d, 0xfeef, 0xfea8, 0xfe6a, 0xfe39, 0xfe16, 0xfe05, 0xfe06, + 0xfe1b, 0xfe43, 0xfe7f, 0xfecd, 0xff2a, 0xff95, 0x0009, 0x0082, 0x00fd, + 0x0173, 0x01e1, 0x0242, 0x0292, 0x02cc, 0x02ec, 0x02f2, 0x02da, 0x02a5, + 0x0253, 0x01e7, 0x0162, 0x00c9, 0x0021, 0xff70, 0xfebc, 0xfe0c, 0xfd68, + 0xfcd5, 0xfc5b, 0xfc00, 0xfbc9, 0xfbb8, 0xfbd2, 0xfc16, 0xfc85, 0xfd1b, + 0xfdd6, 0xfeae, 0xff9e, 0x009c, 0x01a0, 0x02a1, 0x0392, 0x046c, 0x0523, + 0x05b0, 0x060a, 0x062c, 0x0613, 0x05bb, 0x0526, 0x0456, 0x0351, 0x021f, + 0x00c9, 0xff5a, 0xfde1, 0xfc6a, 0xfb05, 0xf9c0, 0xf8aa, 0xf7d0, 0xf73d, + 0xf6fa, 0xf70f, 0xf77e, 0xf848, 0xf96b, 0xfadf, 0xfc9a, 0xfe8f, 0x00ad, + 0x02e3, 0x051a, 0x073f, 0x0939, 0x0af4, 0x0c5a, 0x0d59, 0x0de1, 0x0de5, + 0x0d5c, 0x0c44, 0x0a9e, 0x0870, 0x05c7, 0x02b4, 0xff4e, 0xfbaf, 0xf7f8, + 0xf449, 0xf0c7, 0xed98, 0xeae0, 0xe8c4, 0xe765, 0xe6e3, 0xe756, 0xe8d2, + 0xeb67, 0xef19, 0xf3e9, 0xf9cd, 0x00b5, 0x088a, 0x112b, 0x1a72, 0x2435, + 0x2e42, 0x3866, 0x426b, 0x4c1b, 0x553e, 0x5da2, 0x6516, 0x6b6f, 0x7087, + 0x7441, 0x7686, 0x774a, 0x7686, 0x7441, 0x7087, 0x6b6f, 0x6516, 0x5da2, + 0x553e, 0x4c1b, 0x426b, 0x3866, 0x2e42, 0x2435, 0x1a72, 0x112b, 0x088a, + 0x00b5, 0xf9cd, 0xf3e9, 0xef19, 0xeb67, 0xe8d2, 0xe756, 0xe6e3, 0xe765, + 0xe8c4, 0xeae0, 0xed98, 0xf0c7, 0xf449, 0xf7f8, 0xfbaf, 0xff4e, 0x02b4, + 0x05c7, 0x0870, 0x0a9e, 0x0c44, 0x0d5c, 0x0de5, 0x0de1, 0x0d59, 0x0c5a, + 0x0af4, 0x0939, 0x073f, 0x051a, 0x02e3, 0x00ad, 0xfe8f, 0xfc9a, 0xfadf, + 0xf96b, 0xf848, 0xf77e, 0xf70f, 0xf6fa, 0xf73d, 0xf7d0, 0xf8aa, 0xf9c0, + 0xfb05, 0xfc6a, 0xfde1, 0xff5a, 0x00c9, 0x021f, 0x0351, 0x0456, 0x0526, + 0x05bb, 0x0613, 0x062c, 0x060a, 0x05b0, 0x0523, 0x046c, 0x0392, 0x02a1, + 0x01a0, 0x009c, 0xff9e, 0xfeae, 0xfdd6, 0xfd1b, 0xfc85, 0xfc16, 0xfbd2, + 0xfbb8, 0xfbc9, 0xfc00, 0xfc5b, 0xfcd5, 0xfd68, 0xfe0c, 0xfebc, 0xff70, + 0x0021, 0x00c9, 0x0162, 0x01e7, 0x0253, 0x02a5, 0x02da, 0x02f2, 0x02ec, + 0x02cc, 0x0292, 0x0242, 0x01e1, 0x0173, 0x00fd, 0x0082, 0x0009, 0xff95, + 0xff2a, 0xfecd, 0xfe7f, 0xfe43, 0xfe1b, 0xfe06, 0xfe05, 0xfe16, 0xfe39, + 0xfe6a, 0xfea8, 0xfeef, 0xff3d, 0xff8e, 0xffde, 0x002c, 0x0075, 0x00b5, + 0x00eb, 0x0116, 0x0134, 0x0146, 0x014b, 0x0144, 0x0131, 0x0114, 0x00f0, + 0x00c4, 0x0094, 0x0061, 0x002e, 0xfffc, 0xffcd, 0xffa2, 0xff7e, 0xff60, + 0xff4a, 0xff3b, 0xff34, 0xff35, 0xff3d, 0xff4c, 0xff5f, 0xff77, 0xff93, + 0xffb0, 0xffcf, 0xffed, 0x0009, 0x0024, 0x003c, 0x004f, 0x005f, 0x006b, + 0x0072, 0x0075, 0x0074, 0x006f, 0x0066, 0x005b, 0x004e, 0x003f, 0x002f, + 0x001f, 0x0010, 0x0001, 0xfff3, 0xffe6, 0xffdc, 0xffd3, 0xffcc, 0xffc7, + 0xffc5, 0xffc4, 0xffc4, 0xffc7, 0xffca, 0xffce, 0xffd3, 0xffd8, 0xffde, + 0xffe3, 0xffe8, 0xffed, 0xfff2, 0xfff5, 0xfff9, 0xfffb, 0xfffe, 0xffff, + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0xffd8, 0x0052, 0xff62, + 0x0116, 0xfe3a, 0x02c3, 0xfbd5, 0x0633, 0xf6b8, 0x0e89, 0xe5ee, 0x511e, + 0x511e, 0xe5ee, 0x0e89, 0xf6b8, 0x0633, 0xfbd5, 0x02c3, 0xfe3a, 0x0116, + 0xff62, 0x0052, 0xffd8, 0x0007, 0x0001, /*copy 1*/ + 0x180b, 0x0006, 0x0012, /*copy 18*/ + 0x000f, 0x0010, 0x001c, 0xfab3, 0x3580, 0x8037, 0xa037, 0x0001, 0x0000, + 0x3580, 0x01a4, 0x07c7, 0x07d3, 0x07e6, 0x07df, 0x07ea, 0x07ec, 0x07f2, + 0x0007, 0x0001, /*copy 1*/ + 0x8025, 0x0006, 0x0002, /*copy 2*/ + 0x2a01, 0x824e, 0x0007, 0x0001, /*copy 1*/ + 0x5800, 0x0006, 0x0005, /*copy 5*/ + 0x0000, 0x0c00, 0x0000, 0x0100, 0x0100, 0x0006, 0x8006, 0x0000, /*Rle(6)*/ + 0x000a, 0x0001, /*copy 1*/ + 0x0050, +#define PLUGIN_SIZE 5964 +#ifndef SKIP_PLUGIN_VARNAME +}; +#endif diff --git a/targets/esp32/components/VS1053/include/spectrum_analyzer.h b/targets/esp32/components/VS1053/include/spectrum_analyzer.h new file mode 100644 index 00000000..f163468f --- /dev/null +++ b/targets/esp32/components/VS1053/include/spectrum_analyzer.h @@ -0,0 +1,124 @@ + +const unsigned short PLUGIN[950] = { + /* Compressed plugin */ + 0x0007, 0x0001, 0x8050, 0x0006, 0x0018, 0x3613, 0x0024, 0x3e00, /* 0 */ + 0x3801, 0x0000, 0x16d7, 0xf400, 0x55c0, 0x0000, 0x0c17, 0xf400, /* 8 */ + 0x57c0, 0x0007, 0x9257, 0xb080, 0x0024, 0x3f00, 0x0024, 0x2000, /* 10 */ + 0x0000, 0x36f0, 0x1801, 0x2800, 0x31c0, 0x0007, 0x0001, 0x805c, /* 18 */ + 0x0006, 0x00d6, 0x3e12, 0xb817, 0x3e12, 0x3815, 0x3e05, 0xb814, /* 20 */ + 0x3615, 0x0024, 0x0000, 0x800a, 0x3e10, 0x3801, 0x0006, 0x0000, /* 28 */ + 0x3e10, 0xb803, 0x0000, 0x0303, 0x3e11, 0x3805, 0x3e11, 0xb807, /* 30 */ + 0x3e14, 0x3812, 0xb884, 0x130c, 0x3410, 0x4024, 0x4112, 0x10d0, /* 38 */ + 0x4010, 0x008c, 0x4010, 0x0024, 0xf400, 0x4012, 0x3000, 0x3840, /* 40 */ + 0x3009, 0x3801, 0x0000, 0x0041, 0xfe02, 0x0024, 0x2900, 0x8200, /* 48 */ + 0x48b2, 0x0024, 0x36f3, 0x0844, 0x6306, 0x8845, 0xae3a, 0x8840, /* 50 */ + 0xbf8e, 0x8b41, 0xac32, 0xa846, 0xffc8, 0xabc7, 0x3e01, 0x7800, /* 58 */ + 0xf400, 0x4480, 0x6090, 0x0024, 0x6090, 0x0024, 0xf400, 0x4015, /* 60 */ + 0x3009, 0x3446, 0x3009, 0x37c7, 0x3009, 0x1800, 0x3009, 0x3844, /* 68 */ + 0x48b3, 0xe1e0, 0x4882, 0x4040, 0xfeca, 0x0024, 0x5ac2, 0x0024, /* 70 */ + 0x5a52, 0x0024, 0x4cc2, 0x0024, 0x48ba, 0x4040, 0x4eea, 0x4801, /* 78 */ + 0x4eca, 0x9800, 0xff80, 0x1bc1, 0xf1eb, 0xe3e2, 0xf1ea, 0x184c, /* 80 */ + 0x4c8b, 0xe5e4, 0x48be, 0x9804, 0x488e, 0x41c6, 0xfe82, 0x0024, /* 88 */ + 0x5a8e, 0x0024, 0x525e, 0x1b85, 0x4ffe, 0x0024, 0x48b6, 0x41c6, /* 90 */ + 0x4dd6, 0x48c7, 0x4df6, 0x0024, 0xf1d6, 0x0024, 0xf1d6, 0x0024, /* 98 */ + 0x4eda, 0x0024, 0x0000, 0x0fc3, 0x2900, 0x8200, 0x4e82, 0x0024, /* a0 */ + 0x4084, 0x130c, 0x0006, 0x0100, 0x3440, 0x4024, 0x4010, 0x0024, /* a8 */ + 0xf400, 0x4012, 0x3200, 0x4024, 0xb132, 0x0024, 0x4214, 0x0024, /* b0 */ + 0xf224, 0x0024, 0x6230, 0x0024, 0x0001, 0x0001, 0x2800, 0x2b49, /* b8 */ + 0x0000, 0x0024, 0xf400, 0x40c2, 0x3200, 0x0024, 0xff82, 0x0024, /* c0 */ + 0x48b2, 0x0024, 0xb130, 0x0024, 0x6202, 0x0024, 0x003f, 0xf001, /* c8 */ + 0x2800, 0x2e51, 0x0000, 0x1046, 0xfe64, 0x0024, 0x48be, 0x0024, /* d0 */ + 0x2800, 0x2f40, 0x3a01, 0x8024, 0x3200, 0x0024, 0xb010, 0x0024, /* d8 */ + 0xc020, 0x0024, 0x3a00, 0x0024, 0x36f4, 0x1812, 0x36f1, 0x9807, /* e0 */ + 0x36f1, 0x1805, 0x36f0, 0x9803, 0x36f0, 0x1801, 0x3405, 0x9014, /* e8 */ + 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, 0x0000, 0x36f2, 0x9817, /* f0 */ + 0x0007, 0x0001, 0x80c7, 0x0006, 0x01ae, 0x3e12, 0xb817, 0x3e12, /* f8 */ + 0x3815, 0x3e05, 0xb814, 0x3625, 0x0024, 0x0000, 0x800a, 0x3e10, /* 100 */ + 0x7802, 0x3e10, 0xf804, 0x3e11, 0x7810, 0x3e14, 0x7813, 0x0006, /* 108 */ + 0x0051, 0x3e13, 0xf80e, 0x3e13, 0x4024, 0x3009, 0x3840, 0x3009, /* 110 */ + 0x3852, 0x2911, 0xf140, 0x0006, 0x06d0, 0x3100, 0x5bd2, 0x0006, /* 118 */ + 0xc351, 0x3009, 0x1bc0, 0x3009, 0x0402, 0x6126, 0x0024, 0x0006, /* 120 */ + 0x00d1, 0x2800, 0x4d45, 0x0000, 0x0024, 0x0006, 0x0011, 0xb882, /* 128 */ + 0x184c, 0x3009, 0x3850, 0x0006, 0x0010, 0x3009, 0x3800, 0x2914, /* 130 */ + 0xbec0, 0x0000, 0x1800, 0x0006, 0x0010, 0xb882, 0x0024, 0x2915, /* 138 */ + 0x7ac0, 0x0000, 0x1700, 0x0000, 0x0301, 0x3900, 0x5bc0, 0x0006, /* 140 */ + 0xc351, 0x3009, 0x1bd0, 0x3009, 0x0404, 0x0006, 0x0051, 0x2800, /* 148 */ + 0x3d40, 0x3901, 0x0024, 0x4448, 0x0401, 0x4192, 0x0024, 0x6498, /* 150 */ + 0x2401, 0x001f, 0x4001, 0x6412, 0x0024, 0x0006, 0x0011, 0x2800, /* 158 */ + 0x3c91, 0x0000, 0x058e, 0x2400, 0x4c4e, 0x0000, 0x0013, 0x0006, /* 160 */ + 0x0051, 0x0006, 0x1a03, 0x3100, 0x4024, 0xf212, 0x44c4, 0x4346, /* 168 */ + 0x0024, 0xf400, 0x40d5, 0x3500, 0x8024, 0x612a, 0x0024, 0x0000, /* 170 */ + 0x0024, 0x2800, 0x4c91, 0x0000, 0x0024, 0x3613, 0x0024, 0x3100, /* 178 */ + 0x3800, 0x2915, 0x7dc0, 0xf200, 0x0024, 0x003f, 0xfec2, 0x4082, /* 180 */ + 0x4411, 0x3113, 0x1bc0, 0xa122, 0x0024, 0x0000, 0x2002, 0x6124, /* 188 */ + 0x2401, 0x0000, 0x1002, 0x2800, 0x4648, 0x0000, 0x0024, 0x003f, /* 190 */ + 0xf802, 0x3100, 0x4024, 0xb124, 0x0024, 0x2800, 0x4c00, 0x3900, /* 198 */ + 0x8024, 0x6124, 0x0024, 0x0000, 0x0802, 0x2800, 0x4888, 0x0000, /* 1a0 */ + 0x0024, 0x003f, 0xfe02, 0x3100, 0x4024, 0xb124, 0x0024, 0x2800, /* 1a8 */ + 0x4c00, 0x3900, 0x8024, 0x6124, 0x0024, 0x0000, 0x0402, 0x2800, /* 1b0 */ + 0x4ac8, 0x0000, 0x0024, 0x003f, 0xff02, 0x3100, 0x4024, 0xb124, /* 1b8 */ + 0x0024, 0x2800, 0x4c00, 0x3900, 0x8024, 0x6124, 0x0401, 0x003f, /* 1c0 */ + 0xff82, 0x2800, 0x4c08, 0xb124, 0x0024, 0x3900, 0x8024, 0xb882, /* 1c8 */ + 0x8c4c, 0x3830, 0x4024, 0x0006, 0x0091, 0x3904, 0xc024, 0x0006, /* 1d0 */ + 0x00d1, 0x0000, 0x0013, 0x3100, 0x904c, 0x4202, 0x0024, 0x39f0, /* 1d8 */ + 0x4024, 0x3100, 0x4024, 0x3c00, 0x4024, 0xf400, 0x44c1, 0x34f0, /* 1e0 */ + 0x8024, 0x6126, 0x0024, 0x0006, 0x06d0, 0x2800, 0x5b98, 0x4294, /* 1e8 */ + 0x0024, 0x2400, 0x5b42, 0x0000, 0x0024, 0xf400, 0x4411, 0x3123, /* 1f0 */ + 0x0024, 0x3100, 0x8024, 0x4202, 0x0024, 0x4182, 0x2401, 0x0000, /* 1f8 */ + 0x2002, 0x2800, 0x5b49, 0x0000, 0x0024, 0x3013, 0x184c, 0x30f0, /* 200 */ + 0x7852, 0x6124, 0xb850, 0x0006, 0x0001, 0x2800, 0x55c8, 0x4088, /* 208 */ + 0x44c2, 0x4224, 0x0024, 0x4122, 0x0024, 0x4122, 0x0024, 0xf400, /* 210 */ + 0x4051, 0x2900, 0x7200, 0x0000, 0x5708, 0x4224, 0x0024, 0x4122, /* 218 */ + 0x0024, 0x4122, 0x0024, 0x2900, 0x6780, 0xf400, 0x4051, 0x0002, /* 220 */ + 0x0002, 0x3009, 0x1bd0, 0x3023, 0x1bd2, 0x30e0, 0x4024, 0x6124, /* 228 */ + 0x0024, 0x0000, 0x0024, 0x2800, 0x5b48, 0x0000, 0x0024, 0x3613, /* 230 */ + 0x0024, 0x3e14, 0xc024, 0x2900, 0x1700, 0x3e14, 0x0024, 0x36e3, /* 238 */ + 0x008c, 0x30e0, 0x8024, 0x6822, 0x4411, 0x3123, 0x0024, 0x3900, /* 240 */ + 0x4024, 0x3033, 0x0c4c, 0x0006, 0x0011, 0x6892, 0x04c2, 0xa122, /* 248 */ + 0x0402, 0x6126, 0x0024, 0x0006, 0x0093, 0x2800, 0x64c1, 0x0000, /* 250 */ + 0x0024, 0xb882, 0x184c, 0x3413, 0x3812, 0x0006, 0x00d2, 0x3a00, /* 258 */ + 0x5bd2, 0x3300, 0x4024, 0x0000, 0x0013, 0x3c00, 0x4024, 0xf400, /* 260 */ + 0x44c1, 0x34f0, 0x8024, 0x6126, 0x0024, 0x0006, 0x0111, 0x2800, /* 268 */ + 0x64d8, 0x4294, 0x0024, 0x2400, 0x6482, 0x0000, 0x0024, 0x0003, /* 270 */ + 0xf001, 0x3101, 0x0024, 0xb412, 0x0024, 0x0028, 0x0001, 0x2800, /* 278 */ + 0x6485, 0x6144, 0x0024, 0x0004, 0x0002, 0x2800, 0x6441, 0x4422, /* 280 */ + 0x0024, 0x0000, 0x1002, 0x6422, 0x0024, 0x2800, 0x6480, 0x3900, /* 288 */ + 0x4024, 0x3900, 0x4024, 0x3113, 0x0c4c, 0x36f3, 0x4024, 0x36f3, /* 290 */ + 0xd80e, 0x36f4, 0x5813, 0x36f1, 0x5810, 0x36f0, 0xd804, 0x36f0, /* 298 */ + 0x5802, 0x3405, 0x9014, 0x36f3, 0x0024, 0x36f2, 0x1815, 0x2000, /* 2a0 */ + 0x0000, 0x36f2, 0x9817, 0x0007, 0x0001, 0x1868, 0x0006, 0x000f, /* 2a8 */ + 0x0032, 0x004f, 0x007e, 0x00c8, 0x013d, 0x01f8, 0x0320, 0x04f6, /* 2b0 */ + 0x07e0, 0x0c80, 0x13d8, 0x1f7f, 0x3200, 0x4f5f, 0x61a8, 0x0006, /* 2b8 */ + 0x8008, 0x0000, 0x0007, 0x0001, 0x819e, 0x0006, 0x0054, 0x3e12, /* 2c0 */ + 0xb814, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, 0x3e11, /* 2c8 */ + 0x7806, 0x3e11, 0xf813, 0x3e13, 0xf80e, 0x3e13, 0x4024, 0x3e04, /* 2d0 */ + 0x7810, 0x449a, 0x0040, 0x0001, 0x0003, 0x2800, 0x70c4, 0x4036, /* 2d8 */ + 0x03c1, 0x0003, 0xffc2, 0xb326, 0x0024, 0x0018, 0x0042, 0x4326, /* 2e0 */ + 0x4495, 0x4024, 0x40d2, 0x0000, 0x0180, 0xa100, 0x4090, 0x0010, /* 2e8 */ + 0x0fc2, 0x4204, 0x0024, 0xbc82, 0x4091, 0x459a, 0x0024, 0x0000, /* 2f0 */ + 0x0054, 0x2800, 0x6fc4, 0xbd86, 0x4093, 0x2400, 0x6f85, 0xfe01, /* 2f8 */ + 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x020c, 0x5c56, 0x8a0c, 0x5e53, /* 300 */ + 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x020c, 0x5c56, 0x8a0c, 0x5e52, /* 308 */ + 0x0024, 0x4cb2, 0x4405, 0x0018, 0x0044, 0x654a, 0x0024, 0x2800, /* 310 */ + 0x7dc0, 0x36f4, 0x5810, 0x0007, 0x0001, 0x81c8, 0x0006, 0x0080, /* 318 */ + 0x3e12, 0xb814, 0x0000, 0x800a, 0x3e10, 0x3801, 0x3e10, 0xb803, /* 320 */ + 0x3e11, 0x7806, 0x3e11, 0xf813, 0x3e13, 0xf80e, 0x3e13, 0x4024, /* 328 */ + 0x3e04, 0x7810, 0x449a, 0x0040, 0x0000, 0x0803, 0x2800, 0x7c84, /* 330 */ + 0x30f0, 0x4024, 0x0fff, 0xfec2, 0xa020, 0x0024, 0x0fff, 0xff02, /* 338 */ + 0xa122, 0x0024, 0x4036, 0x0024, 0x0000, 0x1fc2, 0xb326, 0x0024, /* 340 */ + 0x0010, 0x4002, 0x4326, 0x4495, 0x4024, 0x40d2, 0x0000, 0x0180, /* 348 */ + 0xa100, 0x4090, 0x0010, 0x0042, 0x4204, 0x0024, 0xbc82, 0x4091, /* 350 */ + 0x459a, 0x0024, 0x0000, 0x0054, 0x2800, 0x7b84, 0xbd86, 0x4093, /* 358 */ + 0x2400, 0x7b45, 0xfe01, 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x0024, /* 360 */ + 0x5c56, 0x0024, 0x5e53, 0x5e0c, 0x5c43, 0x5f2d, 0x5e46, 0x0024, /* 368 */ + 0x5c56, 0x0024, 0x5e52, 0x0024, 0x4cb2, 0x4405, 0x0010, 0x4004, /* 370 */ + 0x654a, 0x9810, 0x0000, 0x0144, 0xa54a, 0x1bd1, 0x0006, 0x0013, /* 378 */ + 0x3301, 0xc444, 0x687e, 0x2005, 0xad76, 0x8445, 0x4ed6, 0x8784, /* 380 */ + 0x36f3, 0x64c2, 0xac72, 0x8785, 0x4ec2, 0xa443, 0x3009, 0x2440, /* 388 */ + 0x3009, 0x2741, 0x36f3, 0xd80e, 0x36f1, 0xd813, 0x36f1, 0x5806, /* 390 */ + 0x36f0, 0x9803, 0x36f0, 0x1801, 0x2000, 0x0000, 0x36f2, 0x9814, /* 398 */ + 0x0007, 0x0001, 0x8208, 0x0006, 0x000e, 0x4c82, 0x0024, 0x0000, /* 3a0 */ + 0x0024, 0x2000, 0x0005, 0xf5c2, 0x0024, 0x0000, 0x0980, 0x2000, /* 3a8 */ + 0x0000, 0x6010, 0x0024, 0x000a, 0x0001, 0x0050, +#define PLUGIN_SIZE 950 +}; diff --git a/targets/esp32/components/VS1053/include/vs10xx_uc.h b/targets/esp32/components/VS1053/include/vs10xx_uc.h new file mode 100644 index 00000000..b310fca9 --- /dev/null +++ b/targets/esp32/components/VS1053/include/vs10xx_uc.h @@ -0,0 +1,561 @@ +#ifndef VS10XX_MICROCONTROLLER_DEFINITIONS_H +#define VS10XX_MICROCONTROLLER_DEFINITIONS_H + +/* + + VLSI Solution microcontroller definitions for: + VS1063, VS1053 (and VS8053), VS1033, VS1003, VS1103, VS1011. + + v1.01 2012-11-26 HH Added VS1053 recording registers, bug fixes + v1.00 2012-11-23 HH Initial version + +*/ + + + + + +/* SCI registers */ +#define SCI_num_registers 0x0f +#define VS_WRITE_COMMAND 0x02 +#define VS_READ_COMMAND 0x03 + +#define SCI_MODE 0x00 +#define SCI_STATUS 0x01 +#define SCI_BASS 0x02 +#define SCI_CLOCKF 0x03 +#define SCI_DECODE_TIME 0x04 +#define SCI_AUDATA 0x05 +#define SCI_WRAM 0x06 +#define SCI_WRAMADDR 0x07 +#define SCI_HDAT0 0x08 /* VS1063, VS1053, VS1033, VS1003, VS1011 */ +#define SCI_IN0 0x08 /* VS1103 */ +#define SCI_HDAT1 0x09 /* VS1063, VS1053, VS1033, VS1003, VS1011 */ +#define SCI_IN1 0x09 /* VS1103 */ +#define SCI_AIADDR 0x0A +#define SCI_VOL 0x0B +#define SCI_AICTRL0 0x0C /* VS1063, VS1053, VS1033, VS1003, VS1011 */ +#define SCI_MIXERVOL 0x0C /* VS1103 */ +#define SCI_AICTRL1 0x0D /* VS1063, VS1053, VS1033, VS1003, VS1011 */ +#define SCI_ADPCMRECCTL 0x0D /* VS1103 */ +#define SCI_AICTRL2 0x0E +#define SCI_AICTRL3 0x0F + + +/* SCI register recording aliases */ + +#define SCI_RECQUALITY 0x07 /* (WRAMADDR) VS1063 */ +#define SCI_RECDATA 0x08 /* (HDAT0) VS1063 */ +#define SCI_RECWORDS 0x09 /* (HDAT1) VS1063 */ +#define SCI_RECRATE 0x0C /* (AICTRL0) VS1063, VS1053 */ +#define SCI_RECDIV 0x0C /* (AICTRL0) VS1033, VS1003 */ +#define SCI_RECGAIN 0x0D /* (AICTRL1) VS1063, VS1053, VS1033, VS1003 */ +#define SCI_RECMAXAUTO 0x0E /* (AICTRL2) VS1063, VS1053, VS1033 */ +#define SCI_RECMODE 0x0F /* (AICTRL3) VS1063, VS1053 */ + + +/* SCI_MODE bits */ + +#define SM_DIFF_B 0 +#define SM_LAYER12_B 1 /* VS1063, VS1053, VS1033, VS1011 */ +#define SM_RECORD_PATH_B 1 /* VS1103 */ +#define SM_RESET_B 2 +#define SM_CANCEL_B 3 /* VS1063, VS1053 */ +#define SM_OUTOFWAV_B 3 /* VS1033, VS1003, VS1011 */ +#define SM_OUTOFMIDI_B 3 /* VS1103 */ +#define SM_EARSPEAKER_LO_B 4 /* VS1053, VS1033 */ +#define SM_PDOWN_B 4 /* VS1003, VS1103 */ +#define SM_TESTS_B 5 +#define SM_STREAM_B 6 /* VS1053, VS1033, VS1003, VS1011 */ +#define SM_ICONF_B 6 /* VS1103 */ +#define SM_EARSPEAKER_HI_B 7 /* VS1053, VS1033 */ +#define SM_DACT_B 8 +#define SM_SDIORD_B 9 +#define SM_SDISHARE_B 10 +#define SM_SDINEW_B 11 +#define SM_ENCODE_B 12 /* VS1063 */ +#define SM_ADPCM_B 12 /* VS1053, VS1033, VS1003 */ +#define SM_EARSPEAKER_1103_B 12 /* VS1103 */ +#define SM_ADPCM_HP_B 13 /* VS1033, VS1003 */ +#define SM_LINE1_B 14 /* VS1063, VS1053 */ +#define SM_LINE_IN_B 14 /* VS1033, VS1003, VS1103 */ +#define SM_CLK_RANGE_B 15 /* VS1063, VS1053, VS1033 */ +#define SM_ADPCM_1103_B 15 /* VS1103 */ + +#define SM_DIFF (1<< 0) +#define SM_LAYER12 (1<< 1) /* VS1063, VS1053, VS1033, VS1011 */ +#define SM_RECORD_PATH (1<< 1) /* VS1103 */ +#define SM_RESET (1<< 2) +#define SM_CANCEL (1<< 3) /* VS1063, VS1053 */ +#define SM_OUTOFWAV (1<< 3) /* VS1033, VS1003, VS1011 */ +#define SM_OUTOFMIDI (1<< 3) /* VS1103 */ +#define SM_EARSPEAKER_LO (1<< 4) /* VS1053, VS1033 */ +#define SM_PDOWN (1<< 4) /* VS1003, VS1103 */ +#define SM_TESTS (1<< 5) +#define SM_STREAM (1<< 6) /* VS1053, VS1033, VS1003, VS1011 */ +#define SM_ICONF (1<< 6) /* VS1103 */ +#define SM_EARSPEAKER_HI (1<< 7) /* VS1053, VS1033 */ +#define SM_DACT (1<< 8) +#define SM_SDIORD (1<< 9) +#define SM_SDISHARE (1<<10) +#define SM_SDINEW (1<<11) +#define SM_ENCODE (1<<12) /* VS1063 */ +#define SM_ADPCM (1<<12) /* VS1053, VS1033, VS1003 */ +#define SM_EARSPEAKER1103 (1<<12) /* VS1103 */ +#define SM_ADPCM_HP (1<<13) /* VS1033, VS1003 */ +#define SM_LINE1 (1<<14) /* VS1063, VS1053 */ +#define SM_LINE_IN (1<<14) /* VS1033, VS1003, VS1103 */ +#define SM_CLK_RANGE (1<<15) /* VS1063, VS1053, VS1033 */ +#define SM_ADPCM_1103 (1<<15) /* VS1103 */ + +#define SM_ICONF_BITS 2 +#define SM_ICONF_MASK 0x00c0 + +#define SM_EARSPEAKER_1103_BITS 2 +#define SM_EARSPEAKER_1103_MASK 0x3000 + + +/* SCI_STATUS bits */ + +#define SS_REFERENCE_SEL_B 0 /* VS1063, VS1053 */ +#define SS_AVOL_B 0 /* VS1033, VS1003, VS1103, VS1011 */ +#define SS_AD_CLOCK_B 1 /* VS1063, VS1053 */ +#define SS_APDOWN1_B 2 +#define SS_APDOWN2_B 3 +#define SS_VER_B 4 +#define SS_VCM_DISABLE_B 10 /* VS1063, VS1053 */ +#define SS_VCM_OVERLOAD_B 11 /* VS1063, VS1053 */ +#define SS_SWING_B 12 /* VS1063, VS1053 */ +#define SS_DO_NOT_JUMP_B 15 /* VS1063, VS1053 */ + +#define SS_REFERENCE_SEL (1<< 0) /* VS1063, VS1053 */ +#define SS_AVOL (1<< 0) /* VS1033, VS1003, VS1103, VS1011 */ +#define SS_AD_CLOCK (1<< 1) /* VS1063, VS1053 */ +#define SS_APDOWN1 (1<< 2) +#define SS_APDOWN2 (1<< 3) +#define SS_VER (1<< 4) +#define SS_VCM_DISABLE (1<<10) /* VS1063, VS1053 */ +#define SS_VCM_OVERLOAD (1<<11) /* VS1063, VS1053 */ +#define SS_SWING (1<<12) /* VS1063, VS1053 */ +#define SS_DO_NOT_JUMP (1<<15) /* VS1063, VS1053 */ + +#define SS_SWING_BITS 3 +#define SS_SWING_MASK 0x7000 +#define SS_VER_BITS 4 +#define SS_VER_MASK 0x00f0 +#define SS_AVOL_BITS 2 +#define SS_AVOL_MASK 0x0003 + +#define SS_VER_VS1001 0x00 +#define SS_VER_VS1011 0x10 +#define SS_VER_VS1002 0x20 +#define SS_VER_VS1003 0x30 +#define SS_VER_VS1053 0x40 +#define SS_VER_VS8053 0x40 +#define SS_VER_VS1033 0x50 +#define SS_VER_VS1063 0x60 +#define SS_VER_VS1103 0x70 + + +/* SCI_BASS bits */ + +#define ST_AMPLITUDE_B 12 +#define ST_FREQLIMIT_B 8 +#define SB_AMPLITUDE_B 4 +#define SB_FREQLIMIT_B 0 + +#define ST_AMPLITUDE (1<<12) +#define ST_FREQLIMIT (1<< 8) +#define SB_AMPLITUDE (1<< 4) +#define SB_FREQLIMIT (1<< 0) + +#define ST_AMPLITUDE_BITS 4 +#define ST_AMPLITUDE_MASK 0xf000 +#define ST_FREQLIMIT_BITS 4 +#define ST_FREQLIMIT_MASK 0x0f00 +#define SB_AMPLITUDE_BITS 4 +#define SB_AMPLITUDE_MASK 0x00f0 +#define SB_FREQLIMIT_BITS 4 +#define SB_FREQLIMIT_MASK 0x000f + + +/* SCI_CLOCKF bits */ + +#define SC_MULT_B 13 /* VS1063, VS1053, VS1033, VS1103, VS1003 */ +#define SC_ADD_B 11 /* VS1063, VS1053, VS1033, VS1003 */ +#define SC_FREQ_B 0 /* VS1063, VS1053, VS1033, VS1103, VS1003 */ + +#define SC_MULT (1<<13) /* VS1063, VS1053, VS1033, VS1103, VS1003 */ +#define SC_ADD (1<<11) /* VS1063, VS1053, VS1033, VS1003 */ +#define SC_FREQ (1<< 0) /* VS1063, VS1053, VS1033, VS1103, VS1003 */ + +#define SC_MULT_BITS 3 +#define SC_MULT_MASK 0xe000 +#define SC_ADD_BITS 2 +#define SC_ADD_MASK 0x1800 +#define SC_FREQ_BITS 11 +#define SC_FREQ_MASK 0x07ff + +/* The following macro is for VS1063, VS1053, VS1033, VS1003, VS1103. + Divide hz by two when calling if SM_CLK_RANGE = 1 */ +#define HZ_TO_SC_FREQ(hz) (((hz)-8000000+2000)/4000) + +/* The following macro is for VS1011. + The macro will automatically set the clock doubler if XTALI < 16 MHz */ +#define HZ_TO_SCI_CLOCKF(hz) ((((hz)<16000000)?0x8000:0)+((hz)+1000)/2000) + +/* Following are for VS1003 and VS1033 */ +#define SC_MULT_03_10X 0x0000 +#define SC_MULT_03_15X 0x2000 +#define SC_MULT_03_20X 0x4000 +#define SC_MULT_03_25X 0x6000 +#define SC_MULT_03_30X 0x8000 +#define SC_MULT_03_35X 0xa000 +#define SC_MULT_03_40X 0xc000 +#define SC_MULT_03_45X 0xe000 + +/* Following are for VS1053 and VS1063 */ +#define SC_MULT_53_10X 0x0000 +#define SC_MULT_53_20X 0x2000 +#define SC_MULT_53_25X 0x4000 +#define SC_MULT_53_30X 0x6000 +#define SC_MULT_53_35X 0x8000 +#define SC_MULT_53_40X 0xa000 +#define SC_MULT_53_45X 0xc000 +#define SC_MULT_53_50X 0xe000 + +/* Following are for VS1003 and VS1033 */ +#define SC_ADD_03_00X 0x0000 +#define SC_ADD_03_05X 0x0800 +#define SC_ADD_03_10X 0x1000 +#define SC_ADD_03_15X 0x1800 + +/* Following are for VS1053 and VS1063 */ +#define SC_ADD_53_00X 0x0000 +#define SC_ADD_53_10X 0x0800 +#define SC_ADD_53_15X 0x1000 +#define SC_ADD_53_20X 0x1800 + + +/* SCI_WRAMADDR bits */ + +#define SCI_WRAM_X_START 0x0000 +#define SCI_WRAM_Y_START 0x4000 +#define SCI_WRAM_I_START 0x8000 +#define SCI_WRAM_IO_START 0xC000 +#define SCI_WRAM_PARAMETRIC_START 0xC0C0 /* VS1063 */ +#define SCI_WRAM_Y2_START 0xE000 /* VS1063 */ + +#define SCI_WRAM_X_OFFSET 0x0000 +#define SCI_WRAM_Y_OFFSET 0x4000 +#define SCI_WRAM_I_OFFSET 0x8000 +#define SCI_WRAM_IO_OFFSET 0x0000 /* I/O addresses are @0xC000 -> no offset */ +#define SCI_WRAM_PARAMETRIC_OFFSET (0xC0C0-0x1E00) /* VS1063 */ +#define SCI_WRAM_Y2_OFFSET 0x0000 /* VS1063 */ + + +/* SCI_VOL bits */ + +#define SV_LEFT_B 8 +#define SV_RIGHT_B 0 + +#define SV_LEFT (1<<8) +#define SV_RIGHT (1<<0) + +#define SV_LEFT_BITS 8 +#define SV_LEFT_MASK 0xFF00 +#define SV_RIGHT_BITS 8 +#define SV_RIGHT_MASK 0x00FF + + +/* SCI_MIXERVOL bits for VS1103 */ + +#define SMV_ACTIVE_B 15 +#define SMV_GAIN3_B 10 +#define SMV_GAIN2_B 5 +#define SMV_GAIN1_B 0 + +#define SMV_ACTIVE (1<<15) +#define SMV_GAIN3 (1<<10) +#define SMV_GAIN2 (1<< 5) +#define SMV_GAIN1 (1<< 0) + +#define SMV_GAIN3_BITS 5 +#define SMV_GAIN3_MASK 0x7c00 +#define SMV_GAIN2_BITS 5 +#define SMV_GAIN2_MASK 0x04e0 +#define SMV_GAIN1_BITS 5 +#define SMV_GAIN1_MASK 0x001f + + +/* SCI_ADPCMRECCTL bits for VS1103 */ + +#define SARC_DREQ512_B 8 +#define SARC_OUTODADPCM_B 7 +#define SARC_MANUALGAIN_B 6 +#define SARC_GAIN4_B 0 + +#define SARC_DREQ512 (1<<8) +#define SARC_OUTODADPCM (1<<7) +#define SARC_MANUALGAIN (1<<6) +#define SARC_GAIN4 (1<<0) + +#define SARC_GAIN4_BITS 6 +#define SARC_GAIN4_MASK 0x003f + + +/* SCI_RECQUALITY bits for VS1063 */ + +#define RQ_MODE_B 14 +#define RQ_MULT_B 12 +#define RQ_OGG_PAR_SERIAL_NUMBER_B 11 +#define RQ_OGG_LIMIT_FRAME_LENGTH_B 10 +#define RQ_MP3_NO_BIT_RESERVOIR_B 10 +#define RQ_BITRATE_BASE_B 0 + +#define RQ_MODE (1<<14) +#define RQ_MULT (1<<12) +#define RQ_OGG_PAR_SERIAL_NUMBER (1<<11) +#define RQ_OGG_LIMIT_FRAME_LENGTH (1<<10) +#define RQ_MP3_NO_BIT_RESERVOIR (1<<10) +#define RQ_BITRATE_BASE (1<< 0) + +#define RQ_MODE_BITS 2 +#define RQ_MODE_MASK 0xc000 +#define RQ_MULT_BITS 2 +#define RQ_MULT_MASK 0x3000 +#define RQ_BITRATE_BASE_BITS 9 +#define RQ_BITRATE_BASE_MASK 0x01ff + +#define RQ_MODE_QUALITY 0x0000 +#define RQ_MODE_VBR 0x4000 +#define RQ_MODE_ABR 0x8000 +#define RQ_MODE_CBR 0xc000 + +#define RQ_MULT_10 0x0000 +#define RQ_MULT_100 0x1000 +#define RQ_MULT_1000 0x2000 +#define RQ_MULT_10000 0x3000 + + +/* SCI_RECMODE bits for VS1063 */ + +#define RM_63_CODEC_B 15 +#define RM_63_AEC_B 14 +#define RM_63_UART_TX_B 13 +#define RM_63_PAUSE_B 11 +#define RM_63_NO_RIFF_B 10 +#define RM_63_FORMAT_B 4 +#define RM_63_ADC_MODE_B 0 + +#define RM_63_CODEC (1<<15) +#define RM_63_AEC (1<<14) +#define RM_63_UART_TX (1<<13) +#define RM_63_PAUSE (1<<11) +#define RM_63_NO_RIFF (1<<10) +#define RM_63_FORMAT (1<< 4) +#define RM_63_ADC_MODE (1<< 0) + +#define RM_63_FORMAT_BITS 4 +#define RM_63_FORMAT_MASK 0x00f0 +#define RM_63_ADCMODE_BITS 3 +#define RM_63_ADCMODE_MASK 0x0007 + +#define RM_63_FORMAT_IMA_ADPCM 0x0000 +#define RM_63_FORMAT_PCM 0x0010 +#define RM_63_FORMAT_G711_ULAW 0x0020 +#define RM_63_FORMAT_G711_ALAW 0x0030 +#define RM_63_FORMAT_G722_ADPCM 0x0040 +#define RM_63_FORMAT_OGG_VORBIS 0x0050 +#define RM_63_FORMAT_MP3 0x0060 + +#define RM_63_ADC_MODE_JOINT_AGC_STEREO 0x0000 +#define RM_63_ADC_MODE_DUAL_AGC_STEREO 0x0001 +#define RM_63_ADC_MODE_LEFT 0x0002 +#define RM_63_ADC_MODE_RIGHT 0x0003 +#define RM_63_ADC_MODE_MONO 0x0004 + + +/* SCI_RECMODE bits for VS1053 */ + +#define RM_53_FORMAT_B 2 +#define RM_53_ADC_MODE_B 0 + +#define RM_53_FORMAT (1<< 2) +#define RM_53_ADC_MODE (1<< 0) + +#define RM_53_ADCMODE_BITS 2 +#define RM_53_ADCMODE_MASK 0x0003 + +#define RM_53_FORMAT_IMA_ADPCM 0x0000 +#define RM_53_FORMAT_PCM 0x0004 + +#define RM_53_ADC_MODE_JOINT_AGC_STEREO 0x0000 +#define RM_53_ADC_MODE_DUAL_AGC_STEREO 0x0001 +#define RM_53_ADC_MODE_LEFT 0x0002 +#define RM_53_ADC_MODE_RIGHT 0x0003 + + +/* VS1063 definitions */ + +/* VS1063 / VS1053 Parametric */ +#define PAR_CHIP_ID 0x1e00 /* VS1063, VS1053, 32 bits */ +#define PAR_VERSION 0x1e02 /* VS1063, VS1053 */ +#define PAR_CONFIG1 0x1e03 /* VS1063, VS1053 */ +#define PAR_PLAY_SPEED 0x1e04 /* VS1063, VS1053 */ +#define PAR_BITRATE_PER_100 0x1e05 /* VS1063 */ +#define PAR_BYTERATE 0x1e05 /* VS1053 */ +#define PAR_END_FILL_BYTE 0x1e06 /* VS1063, VS1053 */ +#define PAR_RATE_TUNE 0x1e07 /* VS1063, 32 bits */ +#define PAR_PLAY_MODE 0x1e09 /* VS1063 */ +#define PAR_SAMPLE_COUNTER 0x1e0a /* VS1063, 32 bits */ +#define PAR_VU_METER 0x1e0c /* VS1063 */ +#define PAR_AD_MIXER_GAIN 0x1e0d /* VS1063 */ +#define PAR_AD_MIXER_CONFIG 0x1e0e /* VS1063 */ +#define PAR_PCM_MIXER_RATE 0x1e0f /* VS1063 */ +#define PAR_PCM_MIXER_FREE 0x1e10 /* VS1063 */ +#define PAR_PCM_MIXER_VOL 0x1e11 /* VS1063 */ +#define PAR_EQ5_DUMMY 0x1e12 /* VS1063 */ +#define PAR_EQ5_LEVEL1 0x1e13 /* VS1063 */ +#define PAR_EQ5_FREQ1 0x1e14 /* VS1063 */ +#define PAR_EQ5_LEVEL2 0x1e15 /* VS1063 */ +#define PAR_EQ5_FREQ2 0x1e16 /* VS1063 */ +#define PAR_JUMP_POINTS 0x1e16 /* VS1053 */ +#define PAR_EQ5_LEVEL3 0x1e17 /* VS1063 */ +#define PAR_EQ5_FREQ3 0x1e18 /* VS1063 */ +#define PAR_EQ5_LEVEL4 0x1e19 /* VS1063 */ +#define PAR_EQ5_FREQ4 0x1e1a /* VS1063 */ +#define PAR_EQ5_LEVEL5 0x1e1b /* VS1063 */ +#define PAR_EQ5_UPDATED 0x1e1c /* VS1063 */ +#define PAR_SPEED_SHIFTER 0x1e1d /* VS1063 */ +#define PAR_EARSPEAKER_LEVEL 0x1e1e /* VS1063 */ +#define PAR_SDI_FREE 0x1e1f /* VS1063 */ +#define PAR_AUDIO_FILL 0x1e20 /* VS1063 */ +#define PAR_RESERVED0 0x1e21 /* VS1063 */ +#define PAR_RESERVED1 0x1e22 /* VS1063 */ +#define PAR_RESERVED2 0x1e23 /* VS1063 */ +#define PAR_RESERVED3 0x1e24 /* VS1063 */ +#define PAR_LATEST_SOF 0x1e25 /* VS1063, 32 bits */ +#define PAR_LATEST_JUMP 0x1e26 /* VS1053 */ +#define PAR_POSITION_MSEC 0x1e27 /* VS1063, VS1053, 32 bits */ +#define PAR_RESYNC 0x1e29 /* VS1063, VS1053 */ + +/* The following addresses are shared between modes. */ +/* Generic pointer */ +#define PAR_GENERIC 0x1e2a /* VS1063, VS1053 */ + +/* Encoder mode */ +#define PAR_ENC_TX_UART_DIV 0x1e2a /* VS1063 */ +#define PAR_ENC_TX_UART_BYTE_SPEED 0x1e2b /* VS1063 */ +#define PAR_ENC_TX_PAUSE_GPIO 0x1e2c /* VS1063 */ +#define PAR_ENC_AEC_ADAPT_MULTIPLIER 0x1e2d /* VS1063 */ +#define PAR_ENC_RESERVED 0x1e2e /* VS1063 */ +#define PAR_ENC_CHANNEL_MAX 0x1e3c /* VS1063 */ +#define PAR_ENC_SERIAL_NUMBER 0x1e3e /* VS1063 */ + +/* Decoding WMA */ +#define PAR_WMA_CUR_PACKET_SIZE 0x1e2a /* VS1063, VS1053, 32 bits */ +#define PAR_WMA_PACKET_SIZE 0x1e2c /* VS1063, VS1053, 32 bits */ + +/* Decoding AAC */ +#define PAR_AAC_SCE_FOUND_MASK 0x1e2a /* VS1063, VS1053 */ +#define PAR_AAC_CPE_FOUND_MASK 0x1e2b /* VS1063, VS1053 */ +#define PAR_AAC_LFE_FOUND_MASK 0x1e2c /* VS1063, VS1053 */ +#define PAR_AAC_PLAY_SELECT 0x1e2d /* VS1063, VS1053 */ +#define PAR_AAC_DYN_COMPRESS 0x1e2e /* VS1063, VS1053 */ +#define PAR_AAC_DYN_BOOST 0x1e2f /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS 0x1e30 /* VS1063, VS1053 */ +#define PAR_AAC_SBR_PS_FLAGS 0x1e31 /* VS1063 */ + + +/* Decoding MIDI (VS1053) */ +#define PAR_MIDI_BYTES_LEFT 0x1e2a /* VS1053, 32 bits */ + +/* Decoding Vorbis */ +#define PAR_VORBIS_GAIN 0x1e2a 0x1e30 /* VS1063, VS1053 */ + + +/* Bit definitions for parametric registers with bitfields */ +#define PAR_CONFIG1_DIS_WMA_B 15 /* VS1063 */ +#define PAR_CONFIG1_DIS_AAC_B 14 /* VS1063 */ +#define PAR_CONFIG1_DIS_MP3_B 13 /* VS1063 */ +#define PAR_CONFIG1_DIS_FLAC_B 12 /* VS1063 */ +#define PAR_CONFIG1_DIS_CRC_B 8 /* VS1063 */ +#define PAR_CONFIG1_AAC_PS_B 6 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR_B 4 /* VS1063, VS1053 */ +#define PAR_CONFIG1_MIDI_REVERB_B 0 /* VS1053 */ + +#define PAR_CONFIG1_DIS_WMA (1<<15) /* VS1063 */ +#define PAR_CONFIG1_DIS_AAC (1<<14) /* VS1063 */ +#define PAR_CONFIG1_DIS_MP3 (1<<13) /* VS1063 */ +#define PAR_CONFIG1_DIS_FLAC (1<<12) /* VS1063 */ +#define PAR_CONFIG1_DIS_CRC (1<< 8) /* VS1063 */ +#define PAR_CONFIG1_AAC_PS (1<< 6) /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR (1<< 4) /* VS1063, VS1053 */ +#define PAR_CONFIG1_MIDI_REVERB (1<< 0) /* VS1053 */ + +#define PAR_CONFIG1_AAC_PS_BITS 2 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_PS_MASK 0x00c0 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR_BITS 2 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR_MASK 0x0030 /* VS1063, VS1053 */ + +#define PAR_CONFIG1_AAC_SBR_ALWAYS_UPSAMPLE 0x0000 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR_SELECTIVE_UPSAMPLE 0x0010 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR_NEVER_UPSAMPLE 0x0020 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_SBR_DISABLE 0x0030 /* VS1063, VS1053 */ + +#define PAR_CONFIG1_AAC_PS_NORMAL 0x0000 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_PS_DOWNSAMPLED 0x0040 /* VS1063, VS1053 */ +#define PAR_CONFIG1_AAC_PS_DISABLE 0x00c0 /* VS1063, VS1053 */ + +#define PAR_PLAY_MODE_SPEED_SHIFTER_ENA_B 6 /* VS1063 */ +#define PAR_PLAY_MODE_EQ5_ENA_B 5 /* VS1063 */ +#define PAR_PLAY_MODE_PCM_MIXER_ENA_B 4 /* VS1063 */ +#define PAR_PLAY_MODE_AD_MIXER_ENA_B 3 /* VS1063 */ +#define PAR_PLAY_MODE_VU_METER_ENA_B 2 /* VS1063 */ +#define PAR_PLAY_MODE_PAUSE_ENA_B 1 /* VS1063 */ +#define PAR_PLAY_MODE_MONO_ENA_B 0 /* VS1063 */ + +#define PAR_PLAY_MODE_SPEED_SHIFTER_ENA (1<<6) /* VS1063 */ +#define PAR_PLAY_MODE_EQ5_ENA (1<<5) /* VS1063 */ +#define PAR_PLAY_MODE_PCM_MIXER_ENA (1<<4) /* VS1063 */ +#define PAR_PLAY_MODE_AD_MIXER_ENA (1<<3) /* VS1063 */ +#define PAR_PLAY_MODE_VU_METER_ENA (1<<2) /* VS1063 */ +#define PAR_PLAY_MODE_PAUSE_ENA (1<<1) /* VS1063 */ +#define PAR_PLAY_MODE_MONO_ENA (1<<0) /* VS1063 */ + +#define PAR_VU_METER_LEFT_BITS 8 /* VS1063 */ +#define PAR_VU_METER_LEFT_MASK 0xFF00 /* VS1063 */ +#define PAR_VU_METER_RIGHT_BITS 8 /* VS1063 */ +#define PAR_VU_METER_RIGHT_MASK 0x00FF /* VS1063 */ + +#define PAR_AD_MIXER_CONFIG_MODE_B 2 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_RATE_B 2 /* VS1063 */ + +#define PAR_AD_MIXER_CONFIG_MODE_BITS 2 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_MODE_MASK 0x000c /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_RATE_BITS 2 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_RATE_MASK 0x0003 /* VS1063 */ + +#define PAR_AD_MIXER_CONFIG_RATE_192K 0x0000 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_RATE_96K 0x0001 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_RATE_48K 0x0002 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_RATE_24K 0x0003 /* VS1063 */ + +#define PAR_AD_MIXER_CONFIG_MODE_STEREO 0x0000 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_MODE_MONO 0x0040 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_MODE_LEFT 0x0080 /* VS1063 */ +#define PAR_AD_MIXER_CONFIG_MODE_RIGHT 0x00c0 /* VS1063 */ + +#define PAR_AAC_SBR_AND_PS_STATUS_SBR_PRESENT_B 0 /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS_UPSAMPLING_ACTIVE_B 1 /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS_PS_PRESENT_B 2 /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS_PS_ACTIVE_B 3 /* VS1063, VS1053 */ + +#define PAR_AAC_SBR_AND_PS_STATUS_SBR_PRESENT (1<<0) /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS_UPSAMPLING_ACTIVE (1<<1) /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS_PS_PRESENT (1<<2) /* VS1063, VS1053 */ +#define PAR_AAC_SBR_AND_PS_STATUS_PS_ACTIVE (1<<3) /* VS1063, VS1053 */ + + +#endif /* !VS10XX_MICROCONTROLLER_DEFINITIONS_H */ diff --git a/targets/esp32/components/VS1053/src/VS1053.cpp b/targets/esp32/components/VS1053/src/VS1053.cpp new file mode 100644 index 00000000..1d86ebf8 --- /dev/null +++ b/targets/esp32/components/VS1053/src/VS1053.cpp @@ -0,0 +1,665 @@ +#include "VS1053.h" + +#include +#include "esp_log.h" + +static const char* TAG = "VS_SINK"; +void vs_feed(void* sink) { + ((VS1053_SINK*)sink)->run_feed(1024); +} + +unsigned char pcm_wav_header[44] = { + 0x52, 0x49, 0x46, + 0x46, // RIFF + 0xFF, 0xFF, 0xFF, + 0xFF, // size + 0x57, 0x41, 0x56, + 0x45, // WAVE + 0x66, 0x6d, 0x74, + 0x20, // fmt + 0x10, 0x00, 0x00, + 0x00, // subchunk1size + 0x01, 0x00, // audio format - pcm + 0x02, 0x00, // numof channels + 0x44, 0xac, 0x00, + 0x00, //, //samplerate 44k1: 0x44, 0xac, 0x00, 0x00 48k: 48000: 0x80, 0xbb, 0x00, 0x00, + 0x10, 0xb1, 0x02, + 0x00, // byterate + 0x04, 0x00, // blockalign + 0x10, 0x00, // bits per sample - 16 + 0x64, 0x61, 0x74, + 0x61, // subchunk3id -"data" + 0xFF, 0xFF, 0xFF, + 0xFF // subchunk3size (endless) +}; +const char* afName[] = { + "unknown", "RIFF", "Ogg", "MP1", "MP2", "MP3", "AAC MP4", + "AAC ADTS", "AAC ADIF", "FLAC", "WMA", "MIDI", "DSD64", "LATM/LOAS", +}; +VS1053_SINK::VS1053_SINK() { + // PIN CONFIG + // DREQ + ESP_LOGI(TAG, "VS1053_DREQ=%d", CONFIG_GPIO_VS_DREQ); + isRunning = true; + gpio_config_t gpio_conf; + gpio_conf.mode = GPIO_MODE_INPUT; + gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE; + gpio_conf.pull_down_en = GPIO_PULLDOWN_ENABLE; + gpio_conf.intr_type = GPIO_INTR_DISABLE; + gpio_conf.pin_bit_mask = ((uint64_t)(((uint64_t)1) << CONFIG_GPIO_VS_DREQ)); + ESP_ERROR_CHECK(gpio_config(&gpio_conf)); + // CS + ESP_LOGI(TAG, "VS1053_CS=%d", CONFIG_GPIO_VS_CS); + gpio_reset_pin((gpio_num_t)CONFIG_GPIO_VS_CS); + gpio_set_direction((gpio_num_t)CONFIG_GPIO_VS_CS, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)CONFIG_GPIO_VS_CS, 1); + // DCS + ESP_LOGI(TAG, "VS1053_DCS=%d", CONFIG_GPIO_VS_DCS); + gpio_reset_pin((gpio_num_t)CONFIG_GPIO_VS_DCS); + gpio_set_direction((gpio_num_t)CONFIG_GPIO_VS_DCS, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)CONFIG_GPIO_VS_DCS, 1); + // RESET + ESP_LOGI(TAG, "VS1053_RESET=%d", CONFIG_GPIO_VS_RESET); + if (CONFIG_GPIO_VS_RESET >= 0) { + gpio_reset_pin((gpio_num_t)CONFIG_GPIO_VS_RESET); + gpio_set_direction((gpio_num_t)CONFIG_GPIO_VS_RESET, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)CONFIG_GPIO_VS_RESET, 0); + vTaskDelay(100 / portTICK_PERIOD_MS); + gpio_set_level((gpio_num_t)CONFIG_GPIO_VS_RESET, 1); + } +} + +esp_err_t VS1053_SINK::init(spi_host_device_t SPI, + SemaphoreHandle_t* SPI_semaphore) { + esp_err_t ret; + this->SPI_semaphore = SPI_semaphore; + // SPI CONFIG + uint32_t freq = spi_get_actual_clock(APB_CLK_FREQ, 1400000, 128); + spi_device_interface_config_t devcfg; + memset(&devcfg, 0, sizeof(spi_device_interface_config_t)); + ESP_LOGI(TAG, "VS1053 LOWFreq: %d", freq); + + devcfg.clock_speed_hz = freq, devcfg.command_bits = 8, + devcfg.address_bits = 8, devcfg.dummy_bits = 0, devcfg.duty_cycle_pos = 0, + devcfg.cs_ena_pretrans = 0, devcfg.cs_ena_posttrans = 1, devcfg.flags = 0, + devcfg.mode = 0, devcfg.spics_io_num = CONFIG_GPIO_VS_CS, + devcfg.queue_size = 1, + devcfg.pre_cb = NULL, // Specify pre-transfer callback to handle D/C line + devcfg.post_cb = NULL; + + ESP_LOGI(TAG, "spi device interface config done, VERSION : %i", VERSION); + ret = spi_bus_add_device(SPI, &devcfg, &this->SPIHandleLow); + ESP_LOGI(TAG, "spi_bus_add_device=%d", ret); + assert(ret == ESP_OK); + // SPI TEST SLOW-/HIGH-SPEED + vTaskDelay(20 / portTICK_PERIOD_MS); + write_register(SCI_MODE, SM_SDINEW | SM_TESTS | SM_RESET); + ret = test_comm("Slow SPI,Testing VS1053 read/write registers...\n"); + if (ret != ESP_OK) + return ret; + { + freq = spi_get_actual_clock(APB_CLK_FREQ, 6670000, 128); + write_register( + SCI_CLOCKF, + HZ_TO_SC_FREQ(12288000) | SC_MULT_53_45X | + SC_ADD_53_00X); // Normal clock settings multiplyer 3.0 = 12.2 MHz + ESP_LOGI(TAG, "VS1053 HighFreq: %d", freq); + devcfg.clock_speed_hz = freq, devcfg.command_bits = 0, + devcfg.address_bits = 0, devcfg.spics_io_num = CONFIG_GPIO_VS_DCS; + ret = spi_bus_add_device(SPI, &devcfg, &this->SPIHandleFast); + ESP_LOGI(TAG, "spi_bus_add_device=%d", ret); + assert(ret == ESP_OK); + ret = test_comm("Slow SPI,Testing VS1053 read/write registers...\n"); + if (ret != ESP_OK) + return ret; + } + vTaskDelay(100 / portTICK_PERIOD_MS); + + write_mem(PAR_CONFIG1, PAR_CONFIG1_AAC_SBR_SELECTIVE_UPSAMPLE); + write_register(SCI_VOL, 0x0c0c); +#ifndef CONFIG_VS1053_NO_PLUGIN + load_user_code(PLUGIN, PLUGIN_SIZE); +#endif + vTaskDelay(100 / portTICK_PERIOD_MS); + xTaskCreate(vs_feed, "track_feed", 1028 * 20, (void*)this, 1, &task_handle); + //xTaskCreatePinnedToCore(vs_feed, "track_feed", 1028 * 20, (void*)this, 1, &task_handle, 1); + return ESP_OK; +} + +VS1053_SINK::~VS1053_SINK() { + if (task_handle != NULL) + vTaskDelete(task_handle); + command_callbacks.clear(); + task_handle = NULL; + isRunning = false; +} +// LOOP +VS1053_TRACK::VS1053_TRACK(size_t track_id, size_t buffer_size) { + this->track_id = track_id; + this->dataBuffer = xStreamBufferCreate(buffer_size, 1); + // this->run_track(); +} +VS1053_TRACK::~VS1053_TRACK() { + if (dataBuffer != NULL) + vStreamBufferDelete(dataBuffer); + dataBuffer = NULL; +} + +void VS1053_SINK::new_track(std::shared_ptr track) { + tracks.push_back(track); +} +bool VS1053_SINK::is_seekable(VS1053_TRACK::VS_TRACK_STATE* state) { + if (read_register(SCI_STATUS) >> SS_DO_NOT_JUMP_B == 0) { + new_state(*state, VS1053_TRACK::VS_TRACK_STATE::tsPlaybackSeekable); + return true; + } + return false; +} +size_t VS1053_SINK::track_seekable(size_t track_id) { + if (tracks.size()) + if (tracks[0]->track_id == track_id) + return tracks[0]->header_size; + return 0; +} +void VS1053_SINK::cancel_track(VS1053_TRACK::VS_TRACK_STATE* state) { + unsigned short oldMode; + oldMode = read_register(SCI_MODE); + write_register(SCI_MODE, oldMode | SM_CANCEL); + new_state(*state, VS1053_TRACK::VS_TRACK_STATE::tsCancelAwait); +} +bool VS1053_SINK::is_cancelled(VS1053_TRACK::VS_TRACK_STATE* state, + uint8_t endFillByte, size_t endFillBytes) { + if (read_register(SCI_MODE) & SM_CANCEL) + sdi_send_fillers(endFillByte, 2); + else { + sdi_send_fillers(endFillByte, endFillBytes); + new_state(*state, VS1053_TRACK::VS_TRACK_STATE::tsStopped); + return true; + } + return false; +} +void VS1053_SINK::delete_all_tracks(void) { + if (this->tracks.size() > 1) + this->tracks.erase(tracks.begin() + 1, tracks.end()); + if (this->tracks[0]->state != VS1053_TRACK::VS_TRACK_STATE::tsStopped) + new_state(this->tracks[0]->state, VS1053_TRACK::VS_TRACK_STATE::tsCancel); +} +size_t VS1053_SINK::get_track_info(size_t pos, uint8_t& endFillByte, + size_t& endFillBytes) { +#ifdef CONFIG_REPORT_ON_SCREEN + uint16_t sampleRate; + uint32_t byteRate; +#endif + get_audio_format(&audioFormat, &endFillBytes); + + /* It is important to collect endFillByte while still in normal + playback. If we need to later cancel playback or run into any + trouble with e.g. a broken file, we need to be able to repeatedly + send this byte until the decoder has been able to exit. */ + + endFillByte = read_mem(PAR_END_FILL_BYTE); +#ifdef CONFIG_REPORT_ON_SCREEN + + sampleRate = read_register(SCI_AUDATA); + byteRate = read_mem(PAR_BYTERATE); + /* FLAC: byteRate = bitRate / 32 + Others: byteRate = bitRate / 8 + Here we compensate for that difference. */ + if (audioFormat == afFlac) + byteRate *= 4; + + ESP_LOGI(TAG, + "Track %i, " + "%dKiB " + "%1ds %1.1f" + "kb/s %dHz %s %s", + tracks[0]->track_id, pos / (1024 / VS1053_PACKET_SIZE), + read_register(SCI_DECODE_TIME), byteRate * (8.0 / 1000.0), + sampleRate & 0xFFFE, (sampleRate & 1) ? "stereo" : "mono", + afName[audioFormat]); +#endif + return (audioFormat == afMidi || audioFormat == afUnknown) + ? REPORT_INTERVAL_MIDI + : REPORT_INTERVAL; +} + +size_t VS1053_TRACK::feed_data(uint8_t* data, size_t len, + bool STORAGE_VOLATILE) { + if (this->dataBuffer == NULL || !len || + xStreamBufferSpacesAvailable(this->dataBuffer) < len) + return 0; + if (STORAGE_VOLATILE) + if (this->header_size) + xStreamBufferReset(this->dataBuffer); + size_t res = + xStreamBufferSend(this->dataBuffer, (void*)data, len, pdMS_TO_TICKS(100)); + return res; +} +size_t VS1053_SINK::spaces_available(size_t track_id) { + if (this->tracks.size()) + for (auto track : tracks) + if (track->track_id == track_id) + return xStreamBufferSpacesAvailable(track->dataBuffer); + return 0; +} +void VS1053_TRACK::empty_feed() { + if (this->dataBuffer != NULL) + xStreamBufferReset(this->dataBuffer); +} +void VS1053_SINK::new_state(VS1053_TRACK::VS_TRACK_STATE& state, + VS1053_TRACK::VS_TRACK_STATE new_state) { + state = new_state; + ESP_LOGI(TAG, "New state %i", new_state); + if (state_callback != NULL) { + state_callback((uint8_t)new_state); + } +} + +void VS1053_SINK::run_feed(size_t FILL_BUFFER_BEFORE_PLAYBACK) { + while (isRunning) { + uint8_t* item = (uint8_t*)malloc(VS1053_PACKET_SIZE); + if (tracks.size()) { + size_t itemSize = 0; + uint32_t pos = 0; + long nextReportPos = 0; // File pointer where to next collect/report + std::shared_ptr track = tracks.front(); + uint8_t endFillByte = 0; // Byte to send when stopping song + size_t endFillBytes = SDI_END_FILL_BYTES; + playMode = read_mem(PAR_PLAY_MODE); + sdi_send_fillers(endFillByte, endFillBytes); + write_register(SCI_DECODE_TIME, 0); // Reset DECODE_TIME + new_state(track->state, VS1053_TRACK::VS_TRACK_STATE::tsPlaybackStart); + while (track->state != VS1053_TRACK::VS_TRACK_STATE::tsStopped) { + if (this->command_callbacks.size()) { + this->command_callbacks[0](track->track_id); + this->command_callbacks.pop_front(); + } + + switch (track->state) { + case VS1053_TRACK::VS_TRACK_STATE::tsPlaybackStart: + this->new_state( + track->state, + VS1053_TRACK::VS1053_TRACK::VS_TRACK_STATE::tsPlayback); + goto tsPlaybackSeekable; + case VS1053_TRACK::VS_TRACK_STATE::tsPlayback: + if (this->is_seekable(&track->state)) + if (!track->header_size) + track->header_size = VS1053_PACKET_SIZE * pos; + goto tsPlaybackSeekable; + case VS1053_TRACK::VS_TRACK_STATE::tsPlaybackSeekable: + + tsPlaybackSeekable: + itemSize = xStreamBufferReceive(track->dataBuffer, (void*)item, + VS1053_PACKET_SIZE, 10); + if (itemSize) { + this->sdi_send_buffer(item, itemSize); + pos++; + } + break; + case VS1053_TRACK::VS_TRACK_STATE::tsSoftCancel: + if (xStreamBufferBytesAvailable(track->dataBuffer)) + goto tsPlaybackSeekable; + this->new_state(track->state, + VS1053_TRACK::VS_TRACK_STATE::tsCancel); + [[fallthrough]]; + case VS1053_TRACK::VS_TRACK_STATE::tsCancel: + free(item); + track->empty_feed(); + this->cancel_track(&track->state); + [[fallthrough]]; + case VS1053_TRACK::VS_TRACK_STATE::tsCancelAwait: + if (this->is_cancelled(&track->state, endFillByte, endFillBytes)) {} + break; + default: + vTaskDelay(20 / portTICK_PERIOD_MS); + break; + } + if (pos >= nextReportPos) { + nextReportPos += this->get_track_info(pos, endFillByte, endFillBytes); + } + } + if (track->dataBuffer != NULL) + vStreamBufferDelete(track->dataBuffer); + track->dataBuffer = NULL; + tracks.pop_front(); + } + vTaskDelay(50 / portTICK_PERIOD_MS); + } + task_handle = NULL; + vTaskDelete(NULL); +} +// FEED FUNCTIONS + +size_t VS1053_SINK::data_request(std::shared_ptr track) { + return xStreamBufferSpacesAvailable(track->dataBuffer); +} + +void VS1053_SINK::stop_feed() { + if (this->tracks[0]->state <= 4) + new_state(this->tracks[0]->state, VS1053_TRACK::VS_TRACK_STATE::tsCancel); +} +void VS1053_SINK::soft_stop_feed() { + if (this->tracks[0]->state <= 3) + new_state(this->tracks[0]->state, + VS1053_TRACK::VS_TRACK_STATE::tsSoftCancel); +} + +// COMMAND FUCNTIONS +/* The command pipeline recieves command in a structure of uint8_t[]. + */ +uint8_t VS1053_SINK::feed_command(command_callback commandCallback) { + if (this->tracks.size()) { + command_callbacks.push_back(commandCallback); + } else + commandCallback(0); + return 0; +} +void VS1053_SINK::set_volume_logarithmic(size_t vol) { + float value = log10((float)vol / 0xFFFF * 100 + 1); + if (value >= 2.0) + value = 2.0; + size_t logVolume = value / 2 * 100; // *100 + + this->set_volume(logVolume); +} +/** + * set_volume accepts values from 0 to 100 + */ +void VS1053_SINK::set_volume(uint8_t vol) { + vol = vol > 100 ? 0 : 100 - vol; + uint16_t value = (vol << 8) | vol; + write_register(SCI_VOL, value); // Volume left and right +} + +void VS1053_SINK::set_volume(uint8_t left, uint8_t right) { + left = left > 100 ? 0 : 100 - left; + right = right > 100 ? 0 : 100 - right; + uint16_t value = (left << 8) | right; + write_register(SCI_VOL, value); // Volume left and right +} + +void VS1053_SINK::get_audio_format(Audio_Format* audioFormat, + size_t* endFillBytes) { + uint16_t h1 = read_register(SCI_HDAT1); + *audioFormat = afUnknown; + switch (h1) { + case 0x7665: + *audioFormat = afRiff; + goto sdi_end_fill_bytes; + case 0x4444: + *audioFormat = afDsd64; + goto sdi_end_fill_bytes_flac; + case 0x4c41: + *audioFormat = afLatm; + // set OUT_OF_WAV bit of SCI_MODE; + goto sdi_end_fill_bytes_flac; + case 0x4154: + *audioFormat = afAacAdts; + goto sdi_end_fill_bytes; + case 0x4144: + *audioFormat = afAacAdif; + goto sdi_end_fill_bytes; + case 0x574d: + *audioFormat = afWma; + goto sdi_end_fill_bytes; + case 0x4f67: + *audioFormat = afOggVorbis; + goto sdi_end_fill_bytes; + case 0x664c: + *audioFormat = afFlac; + goto sdi_end_fill_bytes_flac; + case 0x4d34: + *audioFormat = afAacMp4; + goto sdi_end_fill_bytes; + case 0x4d54: + *audioFormat = afMidi; + goto sdi_end_fill_bytes; + default: + h1 &= 0xffe6; + if (h1 == 0xffe2) + *audioFormat = afMp2; + else if (h1 == 0xffe4) + *audioFormat = afMp2; + else if (h1 == 0xffe6) + *audioFormat = afMp1; + if (*audioFormat == afUnknown) + goto sdi_end_fill_bytes_flac; + sdi_end_fill_bytes: + *endFillBytes = SDI_END_FILL_BYTES; + break; + sdi_end_fill_bytes_flac: + *endFillBytes = SDI_END_FILL_BYTES_FLAC; + break; + } +} + +// SPI COMMUNICATION TEST +const uint16_t chipNumber[16] = {1001, 1011, 1011, 1003, 1053, 1033, 1063, 1103, + 0, 0, 0, 0, 0, 0, 0, 0}; + +esp_err_t VS1053_SINK::test_comm(const char* header) { + // Test the communication with the VS1053 module. The result wille be returned. + // If DREQ is low, there is problably no VS1053 connected. Pull the line HIGH + // in order to prevent an endless loop waiting for this signal. The rest of the + // software will still work, but readbacks from VS1053 will fail. + + write_register(SCI_AICTRL1, 0xABAD); + write_register(SCI_AICTRL2, 0x7E57); + if (read_register(SCI_AICTRL1) != 0xABAD || + read_register(SCI_AICTRL2) != 0x7E57) { + ESP_LOGI(TAG, "There is something wrong with VS10xx SCI registers\n"); + return ESP_ERR_INVALID_RESPONSE; + } + write_register(SCI_AICTRL1, 0); + write_register(SCI_AICTRL2, 0); + uint16_t ssVer = ((read_register(SCI_STATUS) >> 4) & 15); + if (chipNumber[ssVer]) { + ESP_LOGI(TAG, "Chip is VS%d\n", chipNumber[ssVer]); + if (chipNumber[ssVer] != 1053) { + ESP_LOGI(TAG, "Incorrect chip\n"); + return ESP_ERR_NOT_SUPPORTED; + } + } else { + ESP_LOGI(TAG, "Unknown VS10xx SCI_MODE field SS_VER = %d\n", ssVer); + return ESP_ERR_NOT_FOUND; + } + + return ESP_OK; +} + +// PLUGIN FUNCTION + +void VS1053_SINK::load_user_code(const unsigned short* plugin, + uint16_t sizeofpatch) { + ESP_LOGI(TAG, "Loading patch"); + await_data_request(); + int i = 0; + while (i < sizeofpatch) { + unsigned short addr, n, val; + addr = plugin[i++]; + n = plugin[i++]; + if (n & 0x8000U) { /* RLE run, replicate n samples */ + n &= 0x7FFF; + val = plugin[i++]; + while (n--) { + write_register(addr, val); + } + } else { /* Copy run, copy n samples */ + while (n--) { + val = plugin[i++]; + write_register(addr, val); + } + } + } +} + +// GPIO FUNCTIONS + +void VS1053_SINK::await_data_request() { + while (!gpio_get_level((gpio_num_t)CONFIG_GPIO_VS_DREQ)) + vTaskDelay(1); +} +// WRITE/READ FUNCTIONS + +uint16_t VS1053_SINK::read_register(uint8_t _reg) { + spi_transaction_t SPITransaction; + esp_err_t ret; + await_data_request(); // Wait for DREQ to be HIGH + memset(&SPITransaction, 0, sizeof(spi_transaction_t)); + SPITransaction.length = 16; + SPITransaction.flags |= SPI_TRANS_USE_RXDATA; + SPITransaction.cmd = VS_READ_COMMAND; + SPITransaction.addr = _reg; + if (SPI_semaphore != NULL) + while (xSemaphoreTake(*SPI_semaphore, 1) != pdTRUE) + vTaskDelay(1); + ret = spi_device_transmit(this->SPIHandleLow, &SPITransaction); + assert(ret == ESP_OK); + uint16_t result = (((SPITransaction.rx_data[0] & 0xFF) << 8) | + ((SPITransaction.rx_data[1]) & 0xFF)); + await_data_request(); // Wait for DREQ to be HIGH again + if (SPI_semaphore != NULL) + xSemaphoreGive(*SPI_semaphore); + return result; +} + +bool VS1053_SINK::write_register(uint8_t _reg, uint16_t _value) { + spi_transaction_t SPITransaction; + esp_err_t ret; + + await_data_request(); // Wait for DREQ to be HIGH + memset(&SPITransaction, 0, sizeof(spi_transaction_t)); + SPITransaction.flags |= SPI_TRANS_USE_TXDATA; + SPITransaction.cmd = VS_WRITE_COMMAND; + SPITransaction.addr = _reg; + SPITransaction.tx_data[0] = (_value >> 8) & 0xFF; + SPITransaction.tx_data[1] = (_value & 0xFF); + SPITransaction.length = 16; + if (SPI_semaphore != NULL) + while (xSemaphoreTake(*SPI_semaphore, 1) != pdTRUE) + vTaskDelay(1); + ret = spi_device_transmit(this->SPIHandleLow, &SPITransaction); + assert(ret == ESP_OK); + await_data_request(); // Wait for DREQ to be HIGH again + if (SPI_semaphore != NULL) + xSemaphoreGive(*SPI_semaphore); + return true; +} + +uint32_t VS1053_SINK::read_mem32(uint16_t addr) { + uint16_t result; + + write_register(SCI_WRAMADDR, addr); + // Note: transfer16 does not seem to work + result = read_register(SCI_WRAM); + return result | ((uint32_t)read_register(SCI_WRAM) << 16); +} + +uint32_t VS1053_SINK::read_mem32_counter(uint16_t addr) { + uint16_t msbV1, lsb, msbV2; + uint32_t res; + write_register(SCI_WRAMADDR, addr); + msbV1 = read_register(SCI_WRAM); + write_register(SCI_WRAMADDR, addr); + lsb = read_register(SCI_WRAM); + msbV2 = read_register(SCI_WRAM); + if (lsb < 0x8000U) { + msbV1 = msbV2; + } + res = ((uint32_t)msbV1 << 16) | lsb; + + return res; +} + +uint16_t VS1053_SINK::read_mem(uint16_t addr) { + write_register(SCI_WRAMADDR, addr); + return read_register(SCI_WRAM); +} + +/* + Write 16-bit value to given VS10xx address +*/ +void VS1053_SINK::write_mem(uint16_t addr, uint16_t data) { + write_register(SCI_WRAMADDR, addr); + write_register(SCI_WRAM, data); +} + +/* + Write 32-bit value to given VS10xx address +*/ +void VS1053_SINK::write_mem32(uint16_t addr, uint32_t data) { + write_register(SCI_WRAMADDR, addr); + write_register(SCI_WRAM, (uint16_t)data); + write_register(SCI_WRAM, (uint16_t)(data >> 16)); +} +bool VS1053_SINK::sdi_send_buffer(uint8_t* data, size_t len) { + size_t chunk_length; // Length of chunk 32 byte or shorter + spi_transaction_t SPITransaction; + esp_err_t ret; + if (SPI_semaphore != NULL) + while (xSemaphoreTake(*SPI_semaphore, 1) != pdTRUE) + vTaskDelay(1); + while (len) // More to do? + { + await_data_request(); // Wait for space available + chunk_length = len; + if (len > VS1053_CHUNK_SIZE) { + chunk_length = VS1053_CHUNK_SIZE; + } + len -= chunk_length; + memset(&SPITransaction, 0, sizeof(spi_transaction_t)); + SPITransaction.length = chunk_length * 8; + SPITransaction.tx_buffer = data; + // while(spi_device_acquire_bus(this->SPIHandleFast,portMAX_DELAY)!=ESP_OK){}; + ret = spi_device_transmit(this->SPIHandleFast, &SPITransaction); + // spi_device_release_bus(this->SPIHandleFast); + assert(ret == ESP_OK); + data += chunk_length; + } + if (SPI_semaphore != NULL) + xSemaphoreGive(*SPI_semaphore); + + return true; +} + +bool VS1053_SINK::sdi_send_fillers(uint8_t endFillByte, size_t len) { + size_t chunk_length; // Length of chunk 32 byte or shorter + spi_transaction_t SPITransaction; + esp_err_t ret; + uint8_t data[VS1053_CHUNK_SIZE]; + for (int i = 0; i < VS1053_CHUNK_SIZE; i++) + data[i] = endFillByte; + if (SPI_semaphore != NULL) + while (xSemaphoreTake(*SPI_semaphore, 1) != pdTRUE) + vTaskDelay(1); + while (len) // More to do? + { + await_data_request(); // Wait for space available + chunk_length = len; + if (len > VS1053_CHUNK_SIZE) { + chunk_length = VS1053_CHUNK_SIZE; + } + len -= chunk_length; + + memset(&SPITransaction, 0, sizeof(spi_transaction_t)); + SPITransaction.length = chunk_length * 8; + SPITransaction.tx_buffer = data; + spi_device_acquire_bus(this->SPIHandleFast, portMAX_DELAY); + ret = spi_device_transmit(this->SPIHandleFast, &SPITransaction); + spi_device_release_bus(this->SPIHandleFast); + assert(ret == ESP_OK); + } + if (SPI_semaphore != NULL) + xSemaphoreGive(*SPI_semaphore); + return true; +} + +void VS1053_SINK::wram_write(uint16_t address, uint16_t data) { + write_register(SCI_WRAMADDR, address); + write_register(SCI_WRAM, data); +} + +uint16_t VS1053_SINK::wram_read(uint16_t address) { + write_register(SCI_WRAMADDR, address); // Start reading from WRAM + return read_register(SCI_WRAM); // Read back result +} diff --git a/targets/esp32/main/EspPlayer.cpp b/targets/esp32/main/EspPlayer.cpp index 0d7ed823..7f957e88 100644 --- a/targets/esp32/main/EspPlayer.cpp +++ b/targets/esp32/main/EspPlayer.cpp @@ -13,82 +13,106 @@ #include "BellUtils.h" // for BELL_SLEEP_MS #include "CircularBuffer.h" +#include "DeviceStateHandler.h" // for SpircHandler, DeviceStateHandler::CommandType #include "Logger.h" -#include "SpircHandler.h" // for SpircHandler, SpircHandler::EventType -#include "StreamInfo.h" // for BitWidth, BitWidth::BW_16 -#include "TrackPlayer.h" // for TrackPlayer +#include "StreamInfo.h" // for BitWidth, BitWidth::BW_16 +#include "TrackPlayer.h" // for TrackPlayer EspPlayer::EspPlayer(std::unique_ptr sink, - std::shared_ptr handler) + std::shared_ptr handler) : bell::Task("player", 32 * 1024, 0, 1) { this->handler = handler; this->audioSink = std::move(sink); this->circularBuffer = std::make_shared(1024 * 128); - auto hashFunc = std::hash(); - - this->handler->getTrackPlayer()->setDataCallback( - [this, &hashFunc](uint8_t* data, size_t bytes, std::string_view trackId) { - auto hash = hashFunc(trackId); - this->feedData(data, bytes, hash); - return bytes; - }); + this->handler->trackPlayer->setDataCallback([this](uint8_t* data, + size_t bytes, +#ifdef CONFIG_BELL_NOCODEC + bool STORAGE_VOLATILE, +#endif + size_t trackId) { + this->feedData(data, bytes, trackId); + return bytes; + }); this->isPaused = false; - this->handler->setEventHandler( - [this, &hashFunc](std::unique_ptr event) { - switch (event->eventType) { - case cspot::SpircHandler::EventType::PLAY_PAUSE: - if (std::get(event->data)) { - this->pauseRequested = true; - } else { - this->isPaused = false; - this->pauseRequested = false; - } + this->handler->stateCallback = + [this](cspot::DeviceStateHandler::Command event) { + switch (event.commandType) { + case cspot::DeviceStateHandler::CommandType::PAUSE: + this->pauseRequested = true; + break; + case cspot::DeviceStateHandler::CommandType::PLAY: + this->isPaused = false; + this->pauseRequested = false; break; - case cspot::SpircHandler::EventType::DISC: + case cspot::DeviceStateHandler::CommandType::DISC: this->circularBuffer->emptyBuffer(); + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + tracks.clear(); + this->playlistEnd = true; break; - case cspot::SpircHandler::EventType::FLUSH: + case cspot::DeviceStateHandler::CommandType::FLUSH: this->circularBuffer->emptyBuffer(); break; - case cspot::SpircHandler::EventType::SEEK: + case cspot::DeviceStateHandler::CommandType::SEEK: this->circularBuffer->emptyBuffer(); break; - case cspot::SpircHandler::EventType::PLAYBACK_START: - this->isPaused = true; - this->playlistEnd = false; + case cspot::DeviceStateHandler::CommandType::SKIP_NEXT: + case cspot::DeviceStateHandler::CommandType::SKIP_PREV: this->circularBuffer->emptyBuffer(); break; - case cspot::SpircHandler::EventType::DEPLETED: + case cspot::DeviceStateHandler::CommandType::PLAYBACK_START: + this->circularBuffer->emptyBuffer(); + this->isPaused = false; + this->playlistEnd = false; + if (tracks.size()) + tracks.clear(); + break; + case cspot::DeviceStateHandler::CommandType::PLAYBACK: + tracks.push_back( + std::get>(event.data)); + this->isPaused = false; + this->playlistEnd = false; + break; + case cspot::DeviceStateHandler::CommandType::DEPLETED: + this->circularBuffer->emptyBuffer(); this->playlistEnd = true; break; - case cspot::SpircHandler::EventType::VOLUME: { - int volume = std::get(event->data); + case cspot::DeviceStateHandler::CommandType::VOLUME: { + int volume = std::get(event.data); break; } default: break; } - }); + }; startTask(); } void EspPlayer::feedData(uint8_t* data, size_t len, size_t trackId) { size_t toWrite = len; - while (toWrite > 0) { - this->current_hash = trackId; - size_t written = - this->circularBuffer->write(data + (len - toWrite), toWrite); - if (written == 0) { - BELL_SLEEP_MS(10); + if (!len) { + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + if (this->playlistEnd) { + tracks.clear(); } + } else + while (toWrite > 0) { + this->current_hash = trackId; + size_t written = + this->circularBuffer->write(data + (len - toWrite), toWrite); + if (written == 0) { + BELL_SLEEP_MS(10); + } - toWrite -= written; - } + toWrite -= written; + } } void EspPlayer::runTask() { @@ -103,7 +127,6 @@ void EspPlayer::runTask() { size_t read = this->circularBuffer->read(outBuf.data(), outBuf.size()); if (this->pauseRequested) { this->pauseRequested = false; - std::cout << "Pause requested!" << std::endl; this->isPaused = true; } @@ -111,15 +134,28 @@ void EspPlayer::runTask() { if (read == 0) { if (this->playlistEnd) { - this->handler->notifyAudioEnded(); this->playlistEnd = false; + if (tracks.size()) { + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + tracks.clear(); + } + lastHash = 0; } BELL_SLEEP_MS(10); continue; } else { if (lastHash != current_hash) { + if (lastHash) { + tracks.at(0)->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(tracks[0]); + tracks.pop_front(); + this->handler->trackPlayer->eofCallback(true); + } lastHash = current_hash; - this->handler->notifyAudioReachedPlayback(); + tracks.at(0)->trackMetrics->startTrackPlaying( + tracks.at(0)->requestedPosition); + this->handler->putPlayerState(); } } } else { diff --git a/targets/esp32/main/EspPlayer.h b/targets/esp32/main/EspPlayer.h index 47189231..dfcc2bbf 100644 --- a/targets/esp32/main/EspPlayer.h +++ b/targets/esp32/main/EspPlayer.h @@ -7,27 +7,29 @@ #include // for mutex #include // for string -#include "AudioSink.h" // for AudioSink -#include "BellTask.h" // for Task +#include "AudioSink.h" // for AudioSink +#include "BellTask.h" // for Task +#include "DeviceStateHandler.h" // for DeviceStateHandler namespace bell { class CircularBuffer; } // namespace bell namespace cspot { -class SpircHandler; +class DeviceStateHandler; } // namespace cspot class EspPlayer : public bell::Task { public: EspPlayer(std::unique_ptr sink, - std::shared_ptr spircHandler); + std::shared_ptr handler); void disconnect(); private: std::string currentTrackId; - std::shared_ptr handler; + std::shared_ptr handler; std::unique_ptr audioSink; std::shared_ptr circularBuffer; + std::deque> tracks = {}; void feedData(uint8_t* data, size_t len, size_t); std::atomic pauseRequested = false; diff --git a/targets/esp32/main/Kconfig.projbuild b/targets/esp32/main/Kconfig.projbuild index 64e164cb..cd416e5a 100644 --- a/targets/esp32/main/Kconfig.projbuild +++ b/targets/esp32/main/Kconfig.projbuild @@ -8,10 +8,12 @@ menu "CSPOT Configuration" choice CSPOT_SINK prompt "Sink Device" - default CSPOT_SINK_AC101 + default CSPOT_SINK_INTERNAL help Select audio sink device + config BELL_NOCODEC + bool "VS1053" config CSPOT_SINK_INTERNAL bool "Built-in DAC" config CSPOT_SINK_AC101 @@ -28,17 +30,30 @@ menu "CSPOT Configuration" choice CSPOT_QUALITY prompt "Audio Quality (BPS)" - default CSPOT_QUALITY_320 + default VORBIS_160 help Audio quality (not used currently) - config CSPOT_QUALITY_320 + config VORBIS_320 bool "320 bps" - config CSPOT_QUALITY_160 + config VORBIS_160 bool "160 bps" - config CSPOT_QUALITY_96 + config VORBIS_96 bool "96 bps" endchoice + config CSPOT_AUDIO_FORMAT + int + default 0 if VORBIS_96 + default 1 if VORBIS_160 + default 2 if VORBIS_320 + default 3 if MP3_256 + default 4 if MP3_320 + default 5 if MP3_160 + default 6 if MP3_96 + default 7 if MP3_160_ENC + default 8 if AAC_24 + default 9 if AAC_48 + choice CSPOT_STATUS_LED_TYPE prompt "Status LED type" default CSPOT_STATUS_LED_TYPE_NONE @@ -78,6 +93,13 @@ menu "CSPOT Configuration" login with username and password endmenu + config UPDATE_FUTURE_TRACKS + int "Send tracks to spotify" + range 0 100 + default 10 + help + How many tracks are visible in the currently playing header + config CSPOT_STATUS_LED_GPIO int "Status LED GPIO number" range 0 48 diff --git a/targets/esp32/main/VSPlayer.cpp b/targets/esp32/main/VSPlayer.cpp new file mode 100644 index 00000000..7df9e5b2 --- /dev/null +++ b/targets/esp32/main/VSPlayer.cpp @@ -0,0 +1,116 @@ +#include "VSPlayer.h" + +#include // for uint8_t +#include // for operator<<, basic_ostream, endl, cout +#include // for shared_ptr, make_shared, make_unique +#include // for scoped_lock +#include // for get + +#include "TrackPlayer.h" // for TrackPlayer + +VSPlayer::VSPlayer(std::shared_ptr handler, + std::shared_ptr vsSink) { + this->handler = handler; + this->vsSink = vsSink; + this->vsSink->state_callback = [this](uint8_t state) { + this->state_callback(state); + }; + + this->handler->trackPlayer->setDataCallback( + [this](uint8_t* data, size_t bytes, size_t trackId, + bool STORAGE_VOLATILE) { + if (!this->track) { + this->track = std::make_shared(trackId, 4098 * 16); + this->vsSink->new_track(this->track); + } + if (trackId != this->track->track_id) { + this->vsSink->soft_stop_feed(); + this->track = std::make_shared(trackId, 4098 * 16); + this->vsSink->new_track(this->track); + } + return this->track->feed_data(data, bytes, STORAGE_VOLATILE); + }, + [this](size_t trackId) { return this->vsSink->track_seekable(trackId); }, + [this](size_t trackId) { + return this->vsSink->spaces_available(trackId); + }); + + this->isPaused = false; + + this->handler->stateCallback = + [this](cspot::DeviceStateHandler::Command event) { + switch (event.commandType) { + case cspot::DeviceStateHandler::CommandType::PAUSE: + if (this->track) + this->vsSink->new_state(this->vsSink->tracks[0]->state, + VS1053_TRACK::tsPlaybackPaused); + break; + case cspot::DeviceStateHandler::CommandType::PLAY: + if (this->track) + this->vsSink->new_state(this->vsSink->tracks[0]->state, + VS1053_TRACK::tsPlaybackSeekable); + break; + case cspot::DeviceStateHandler::CommandType::DISC: + this->track = nullptr; + this->vsSink->delete_all_tracks(); + this->vsSink->stop_feed(); + //this->currentTrack = nullptr; + this->futureTrack = nullptr; + break; + case cspot::DeviceStateHandler::CommandType::FLUSH: + this->track->empty_feed(); + break; + //case cspot::DeviceStateHandler::CommandType::SEEK: + //break; + case cspot::DeviceStateHandler::CommandType::PLAYBACK_START: + break; + case cspot::DeviceStateHandler::CommandType::PLAYBACK: + this->isPaused = true; + this->playlistEnd = false; + if (this->currentTrack != nullptr) + this->futureTrack = + std::get>(event.data); + else + this->currentTrack = + std::get>(event.data); + break; + case cspot::DeviceStateHandler::CommandType::DEPLETED: + this->futureTrack = nullptr; + this->vsSink->stop_feed(); + break; + case cspot::DeviceStateHandler::CommandType::VOLUME: { + this->volume = std::get(event.data); + this->vsSink->feed_command([this](uint8_t) { + this->vsSink->set_volume_logarithmic(this->volume); + }); + break; + } + default: + break; + } + }; +} + +void VSPlayer::state_callback(uint8_t state) { + if (state == 1) { + currentTrack->trackMetrics->startTrackPlaying( + currentTrack->requestedPosition); + this->handler->putPlayerState(); + } + if (state == 7) { + currentTrack->trackMetrics->endTrack(); + this->handler->ctx->playbackMetrics->sendEvent(currentTrack); + if (futureTrack != nullptr) { + currentTrack = futureTrack; + futureTrack = nullptr; + } else { + currentTrack = nullptr; + this->track = nullptr; + } + } +} + +void VSPlayer::disconnect() { + isRunning = false; + std::scoped_lock lock(runningMutex); +} diff --git a/targets/esp32/main/VSPlayer.h b/targets/esp32/main/VSPlayer.h new file mode 100644 index 00000000..8dd27bcc --- /dev/null +++ b/targets/esp32/main/VSPlayer.h @@ -0,0 +1,37 @@ +#pragma once + +#include // for size_t +#include // for uint8_t +#include // for atomic +#include // for shared_ptr, unique_ptr +#include // for mutex +#include // for string + +#include "DeviceStateHandler.h" // for DeviceStateHandler, DeviceStateHandler::CommandType +#include "VS1053.h" +namespace cspot { +class DeviceStateHandler; +} // namespace cspot + +class VSPlayer { + public: + VSPlayer(std::shared_ptr handler, + std::shared_ptr vsSink = NULL); + void disconnect(); + size_t volume = 0; + + private: + std::string currentTrackId; + std::shared_ptr vsSink; + std::shared_ptr handler; + std::shared_ptr track = nullptr; + std::shared_ptr futureTrack = nullptr, + currentTrack = nullptr; + void state_callback(uint8_t state); + + std::atomic pauseRequested = false; + std::atomic isPaused = true; + std::atomic isRunning = true; + std::mutex runningMutex; + std::atomic playlistEnd = false; +}; diff --git a/targets/esp32/main/VSinit.h b/targets/esp32/main/VSinit.h new file mode 100644 index 00000000..1b08bd01 --- /dev/null +++ b/targets/esp32/main/VSinit.h @@ -0,0 +1,114 @@ + +#include +#include +#include +#include +#include +#include "esp_log.h" +#include "esp_vfs_fat.h" +#include "sdmmc_cmd.h" + +#include "VS1053.h" + +#define MOUNT_POINT "/sdcard" + +SemaphoreHandle_t SPI_semaphore; +#define TAG "INIT" +void initAudioSink(std::shared_ptr VS1053) { + esp_err_t ret; + // SPI SETUP + spi_bus_config_t bus_cfg; + memset(&bus_cfg, 0, sizeof(spi_bus_config_t)); + bus_cfg.sclk_io_num = CONFIG_GPIO_CLK; + bus_cfg.mosi_io_num = CONFIG_GPIO_MOSI; + bus_cfg.miso_io_num = CONFIG_GPIO_MISO; + bus_cfg.quadwp_io_num = -1; + bus_cfg.quadhd_io_num = -1; + ESP_LOGI("vsInit", "spi config done"); + ret = spi_bus_initialize(HSPI_HOST, &bus_cfg, 1); + assert(ret == ESP_OK); + SPI_semaphore = xSemaphoreCreateMutex(); + + // VS1053 SETUP + VS1053->init(HSPI_HOST, &SPI_semaphore); + if (CONFIG_GPIO_SD_CS >= 0) { + sdspi_device_config_t sd_device = SDSPI_DEVICE_CONFIG_DEFAULT(); + sd_device.gpio_cs = (gpio_num_t)CONFIG_GPIO_SD_CS; + sd_device.gpio_int = (gpio_num_t)-1; + gpio_install_isr_service(0); + sdspi_dev_handle_t sd_spi_handle; + ret = sdspi_host_init(); + ESP_ERROR_CHECK(ret); + ret = sdspi_host_init_device(&sd_device, &sd_spi_handle); + ESP_ERROR_CHECK(ret); + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + host.slot = sd_spi_handle; + gpio_reset_pin((gpio_num_t)CONFIG_GPIO_SD_CS); + gpio_set_direction((gpio_num_t)CONFIG_GPIO_SD_CS, GPIO_MODE_OUTPUT); + + esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED + .max_files = 5, + .allocation_unit_size = 16 * 1024}; + ESP_LOGI(TAG, "Initializing SD card"); + /* + ret = esp_vfs_fat_sdspi_mount("/sdcard", &host, &sd_device, &mount_config, &card); + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount filesystem. " + "If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option."); + } + else { + ESP_LOGE(TAG, "Failed to initialize the card (%s). " + "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); + } + } + */ + sdmmc_card_t* card = (sdmmc_card_t*)malloc(sizeof(sdmmc_card_t)); + + ESP_LOGI(TAG, "Filesystem mounted"); + if (ret == ESP_OK) + sdmmc_card_print_info(stdout, card); + ret = esp_vfs_fat_sdspi_mount("/sdcard", &host, &sd_device, &mount_config, + &card); + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, + "Failed to mount filesystem. " + "If you want the card to be formatted, set the " + "CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option."); + } else { + ESP_LOGE(TAG, + "Failed to initialize the card (%s). " + "Make sure SD card lines have pull-up resistors in place.", + esp_err_to_name(ret)); + } + } else { + struct dirent* entry; + struct stat file_stat; + DIR* dir = opendir(MOUNT_POINT); + char n_name[280]; + if (!dir) + printf("no dir\n"); + while ((entry = readdir(dir)) != NULL) { + sprintf(n_name, "%s/%s", MOUNT_POINT, entry->d_name); + printf("%s\n", n_name); + printf("name:%s, ino: %i\n", entry->d_name, entry->d_ino); + printf("stat_return_value:%i\n", stat(n_name, &file_stat)); + printf("stat_mode:%i\n", file_stat.st_mode); + } + dir = opendir(MOUNT_POINT "/TRACKS"); + if (!dir) + printf("no dir\n"); + while ((entry = readdir(dir)) != NULL) { + printf("%s\n", entry->d_name); + } + closedir(dir); + } + } + VS1053->write_register(SCI_VOL, 10 | 10 << 8); +} \ No newline at end of file diff --git a/targets/esp32/main/main.cpp b/targets/esp32/main/main.cpp index d0ba2ba5..8f37e3aa 100644 --- a/targets/esp32/main/main.cpp +++ b/targets/esp32/main/main.cpp @@ -7,11 +7,10 @@ #include #include #include "BellHTTPServer.h" -#include "BellLogger.h" // for setDefaultLogger, AbstractLogger +#include "BellLogger.h" // for setDefaultLogger, AbstractLogger #include "BellTask.h" #include "civetweb.h" #include "esp_event.h" -#include "esp_log.h" #include "esp_spiffs.h" #include "esp_system.h" #include "esp_wifi.h" @@ -22,11 +21,8 @@ #include "protocol_examples_common.h" #include "sdkconfig.h" -#include "EspPlayer.h" - #include #include -#include #include #include "BellTask.h" @@ -34,9 +30,15 @@ #include "BellUtils.h" #include "Logger.h" +#include "esp_log.h" #define DEVICE_NAME CONFIG_CSPOT_DEVICE_NAME +#ifdef CONFIG_BELL_NOCODEC +#include "VSPlayer.h" +#include "VSinit.h" +#else +#include "EspPlayer.h" #ifdef CONFIG_CSPOT_SINK_INTERNAL #include #endif @@ -55,18 +57,16 @@ #ifdef CONFIG_CSPOT_SINK_TAS5711 #include #endif - -static const char* TAG = "cspot"; - +#endif extern "C" { - void app_main(void); +void app_main(void); } class ZeroconfAuthenticator { -public: - ZeroconfAuthenticator() {}; - ~ZeroconfAuthenticator() {}; + public: + ZeroconfAuthenticator(){}; + ~ZeroconfAuthenticator(){}; // Authenticator state int serverPort = 7864; @@ -83,14 +83,12 @@ class ZeroconfAuthenticator { server->registerGet("/spotify_info", [this](struct mg_connection* conn) { return this->server->makeJsonResponse(this->blob->buildZeroconfInfo()); - }); - + }); server->registerGet("/close", [this](struct mg_connection* conn) { this->onClose(); return this->server->makeEmptyResponse(); - }); - + }); server->registerPost("/spotify_info", [this](struct mg_connection* conn) { nlohmann::json obj; @@ -124,48 +122,57 @@ class ZeroconfAuthenticator { } return server->makeJsonResponse(obj.dump()); - }); - + }); // Register mdns service, for spotify to find us bell::MDNSService::registerService( - blob->getDeviceName(), "_spotify-connect", "_tcp", "", serverPort, - { {"VERSION", "1.0"}, {"CPath", "/spotify_info"}, {"Stack", "SP"} }); + blob->getDeviceName(), "_spotify-connect", "_tcp", "", serverPort, + {{"VERSION", "1.0"}, {"CPath", "/spotify_info"}, {"Stack", "SP"}}); std::cout << "Waiting for spotify app to connect..." << std::endl; } }; class CSpotTask : public bell::Task { -private: - std::unique_ptr handler; + private: + //std::unique_ptr handler; +#ifndef CONFIG_BELL_NOCODEC std::unique_ptr audioSink; +#endif -public: - CSpotTask() : bell::Task("cspot", 8 * 1024, 0, 0) { startTask(); } + public: + CSpotTask() : bell::Task("cspot", 32 * 1024, 0, 0) { + startTask(); + } void runTask() { mdns_init(); mdns_hostname_set("cspot"); +#ifdef CONFIG_BELL_NOCODEC + std::shared_ptr audioSink; + audioSink = std::make_shared(); + initAudioSink(audioSink); +#else #ifdef CONFIG_CSPOT_SINK_INTERNAL -auto audioSink = std::make_unique(); + auto audioSink = std::make_unique(); #endif #ifdef CONFIG_CSPOT_SINK_AC101 -auto audioSink = std::make_unique(); + auto audioSink = std::make_unique(); #endif #ifdef CONFIG_CSPOT_SINK_ES8388 -auto audioSink = std::make_unique(); + auto audioSink = std::make_unique(); #endif #ifdef CONFIG_CSPOT_SINK_ES9018 -auto audioSink = std::make_unique(); + auto audioSink = std::make_unique(); #endif #ifdef CONFIG_CSPOT_SINK_PCM5102 -auto audioSink = std::make_unique(); + auto audioSink = std::make_unique(); #endif #ifdef CONFIG_CSPOT_SINK_TAS5711 -auto audioSink = std::make_unique(); + auto audioSink = std::make_unique(); #endif audioSink->setParams(44100, 2, 16); audioSink->volumeChanged(160); +#endif auto loggedInSemaphore = std::make_shared(1); @@ -174,18 +181,19 @@ auto audioSink = std::make_unique(); zeroconfServer->onClose = [&isRunning]() { isRunning = false; - }; + }; auto loginBlob = std::make_shared(DEVICE_NAME); #ifdef CONFIG_CSPOT_LOGIN_PASS - loginBlob->loadUserPass(CONFIG_CSPOT_LOGIN_USERNAME, CONFIG_CSPOT_LOGIN_PASSWORD); + loginBlob->loadUserPass(CONFIG_CSPOT_LOGIN_USERNAME, + CONFIG_CSPOT_LOGIN_PASSWORD); loggedInSemaphore->give(); #else zeroconfServer->blob = loginBlob; zeroconfServer->onAuthSuccess = [loggedInSemaphore]() { loggedInSemaphore->give(); - }; + }; zeroconfServer->registerHandlers(); #endif loggedInSemaphore->wait(); @@ -195,15 +203,20 @@ auto audioSink = std::make_unique(); if (ctx->config.authData.size() > 0) { // when credentials file is set, then store reusable credentials - // Start spirc task - auto handler = std::make_shared(ctx); + // Start device handler task + auto handler = std::make_shared(ctx); // Start handling mercury messages ctx->session->startTask(); // Create a player, pass the handler - auto player = std::make_shared(std::move(audioSink), std::move(handler)); - +#ifndef CONFIG_BELL_NOCODEC + auto player = + std::make_shared(std::move(audioSink), std::move(handler)); +#else + auto player = + std::make_shared(std::move(handler), std::move(audioSink)); +#endif // If we wanted to handle multiple devices, we would halt this loop // when a new zeroconf login is requested, and reinitialize the session while (isRunning) { @@ -213,28 +226,26 @@ auto audioSink = std::make_unique(); // Never happens, but required for above case handler->disconnect(); player->disconnect(); - } } }; void init_spiffs() { - esp_vfs_spiffs_conf_t conf = { .base_path = "/spiffs", + esp_vfs_spiffs_conf_t conf = {.base_path = "/spiffs", .partition_label = NULL, .max_files = 5, - .format_if_mount_failed = true }; + .format_if_mount_failed = true}; esp_err_t ret = esp_vfs_spiffs_register(&conf); if (ret != ESP_OK) { if (ret == ESP_FAIL) { - ESP_LOGE(TAG, "Failed to mount or format filesystem"); - } - else if (ret == ESP_ERR_NOT_FOUND) { - ESP_LOGE(TAG, "Failed to find SPIFFS partition"); - } - else { - ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret)); + ESP_LOGE("SPIFFS", "Failed to mount or format filesystem"); + } else if (ret == ESP_ERR_NOT_FOUND) { + ESP_LOGE("SPIFFS", "Failed to find SPIFFS partition"); + } else { + ESP_LOGE("SPIFFS", "Failed to initialize SPIFFS (%s)", + esp_err_to_name(ret)); } return; } @@ -242,11 +253,10 @@ void init_spiffs() { size_t total = 0, used = 0; ret = esp_spiffs_info(conf.partition_label, &total, &used); if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", - esp_err_to_name(ret)); - } - else { - ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used); + ESP_LOGE("SPIFFS", "Failed to get SPIFFS partition information (%s)", + esp_err_to_name(ret)); + } else { + ESP_LOGE("SPIFFS", "Partition size: total: %d, used: %d", total, used); } } @@ -256,7 +266,7 @@ void app_main(void) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || - ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } @@ -273,11 +283,11 @@ void app_main(void) { // statusLed->setStatus(StatusLed::WIFI_CONNECTED); - ESP_LOGI(TAG, "Connected to AP, start spotify receiver"); + ESP_LOGI("MAIN", "Connected to AP, start spotify receiver"); //auto taskHandle = xTaskCreatePinnedToCore(&cspotTask, "cspot", 12*1024, NULL, 5, NULL, 1); /*auto taskHandle = */ bell::setDefaultLogger(); - bell::enableTimestampLogging(); + //bell::enableTimestampLogging(); auto task = std::make_unique(); vTaskSuspend(NULL); }