Code Monkey home page Code Monkey logo

agents's Introduction

The LiveKit icon, the name of the repository and some sample code in the background.

LiveKit: Real-time video, audio and data for developers

LiveKit is an open source project that provides scalable, multi-user conferencing based on WebRTC. It's designed to provide everything you need to build real-time video audio data capabilities in your applications.

LiveKit's server is written in Go, using the awesome Pion WebRTC implementation.

GitHub stars Slack community Twitter Follow GitHub release (latest SemVer) GitHub Workflow Status License

Features

Documentation & Guides

https://docs.livekit.io

Live Demos

Ecosystem

  • Agents: build real-time multimodal AI applications with programmable backend participants
  • Egress: record or multi-stream rooms and export individual tracks
  • Ingress: ingest streams from external sources like RTMP, WHIP, HLS, or OBS Studio

SDKs & Tools

Client SDKs

Client SDKs enable your frontend to include interactive, multi-user experiences.

Language Repo Declarative UI Links
JavaScript (TypeScript) client-sdk-js React docs | JS example | React example
Swift (iOS / MacOS) client-sdk-swift Swift UI docs | example
Kotlin (Android) client-sdk-android Compose docs | example | Compose example
Flutter (all platforms) client-sdk-flutter native docs | example
Unity WebGL client-sdk-unity-web docs
React Native (beta) client-sdk-react-native native
Rust client-sdk-rust

Server SDKs

Server SDKs enable your backend to generate access tokens, call server APIs, and receive webhooks. In addition, the Go SDK includes client capabilities, enabling you to build automations that behave like end-users.

Language Repo Docs
Go server-sdk-go docs
JavaScript (TypeScript) server-sdk-js docs
Ruby server-sdk-ruby
Java (Kotlin) server-sdk-kotlin
Python (community) python-sdks
PHP (community) agence104/livekit-server-sdk-php

Tools

Install

Tip

We recommend installing LiveKit CLI along with the server. It lets you access server APIs, create tokens, and generate test traffic.

The following will install LiveKit's media server:

MacOS

brew install livekit

Linux

curl -sSL https://get.livekit.io | bash

Windows

Download the latest release here

Getting Started

Starting LiveKit

Start LiveKit in development mode by running livekit-server --dev. It'll use a placeholder API key/secret pair.

API Key: devkey
API Secret: secret

To customize your setup for production, refer to our deployment docs

Creating access token

A user connecting to a LiveKit room requires an access token. Access tokens (JWT) encode the user's identity and the room permissions they've been granted. You can generate a token with our CLI:

livekit-cli create-token \
    --api-key devkey --api-secret secret \
    --join --room my-first-room --identity user1 \
    --valid-for 24h

Test with example app

Head over to our example app and enter a generated token to connect to your LiveKit server. This app is built with our React SDK.

Once connected, your video and audio are now being published to your new LiveKit instance!

Simulating a test publisher

livekit-cli join-room \
    --url ws://localhost:7880 \
    --api-key devkey --api-secret secret \
    --room my-first-room --identity bot-user1 \
    --publish-demo

This command publishes a looped demo video to a room. Due to how the video clip was encoded (keyframes every 3s), there's a slight delay before the browser has sufficient data to begin rendering frames. This is an artifact of the simulation.

Deployment

Use LiveKit Cloud

LiveKit Cloud is the fastest and most reliable way to run LiveKit. Every project gets free monthly bandwidth and transcoding credits.

Sign up for LiveKit Cloud.

Self-host

Read our deployment docs for more information.

Building from source

Pre-requisites:

  • Go 1.22+ is installed
  • GOPATH/bin is in your PATH

Then run

git clone https://github.com/livekit/livekit
cd livekit
./bootstrap.sh
mage

Contributing

We welcome your contributions toward improving LiveKit! Please join us on Slack to discuss your ideas and/or PRs.

License

LiveKit server is licensed under Apache License v2.0.


LiveKit Ecosystem
Real-time SDKsReact Components · Browser · iOS/macOS · Android · Flutter · React Native · Rust · Node.js · Python · Unity (web) · Unity (beta)
Server APIsNode.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (community)
Agents FrameworksPython · Playground
ServicesLivekit server · Egress · Ingress · SIP
ResourcesDocs · Example apps · Cloud · Self-hosting · CLI

agents's People

Contributors

brightsparc avatar calinr avatar cs50victor avatar davidzhao avatar dsa avatar keepingitneil avatar lukasio avatar mattherzog avatar ocupe avatar seanmuirhead avatar theomonnom avatar ty-elastic avatar vanics avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

agents's Issues

ZeroDivisionError in voice assistant during function calling and answering

Just tried function calling example with following versions:

livekit-agents==0.7.0
livekit-plugins-openai==0.5.0
livekit-plugins-deepgram==0.5.0
livekit-plugins-elevenlabs==0.5.0
livekit-plugins-silero==0.5.0

When i request toggle lights, I get ZeroDivisionError error:

Task exception was never retrieved
future: <Task finished name='Task-6761' coro=<entrypoint.<locals>._answer_light_toggling() done, defined at /path/to/project/test.py:65> exception=ZeroDivisionError('float division by zero')>

Traceback (most recent call last):
  File "/path/to/project/test.py", line 80, in _answer_light_toggling
    await assistant.say(stream)
  File "/path/to/packages/livekit/agents/voice_assistant/assistant.py", line 225, in say
    await self._start_speech(data, interrupt_current_if_possible=True)
  File "/path/to/packages/livekit/agents/voice_assistant/assistant.py", line 634, in _start_speech
    await self._play_task
  File "/path/to/packages/livekit/agents/voice_assistant/assistant.py", line 712, in _play_speech_if_validated
    await _synthesize_task
  File "/path/to/packages/livekit/agents/voice_assistant/assistant.py", line 818, in _synthesize_task
    await _forward_task
  File "/path/to/packages/livekit/agents/voice_assistant/assistant.py", line 773, in _forward_stream
    tts_forwarder.mark_audio_segment_end()
  File "/path/to/packages/livekit/agents/transcription/tts_forwarder.py", line 170, in mark_audio_segment_end
    seg.avg_speed = len(self._calc_hyphenes(seg.text)) / seg.audio_duration
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
ZeroDivisionError: float division by zero
Here is the `test.py` file content

import asyncio
import logging
from enum import Enum
from typing import Annotated

from livekit.agents import (
    JobContext,
    JobRequest,
    WorkerOptions,
    cli,
    llm,
)
from livekit.agents.voice_assistant import AssistantContext, VoiceAssistant
from livekit.plugins import deepgram, elevenlabs, openai, silero


class Room(Enum):
    BEDROOM = "bedroom"
    LIVING_ROOM = "living room"
    KITCHEN = "kitchen"
    BATHROOM = "bathroom"
    OFFICE = "office"


class AssistantFnc(llm.FunctionContext):
    @llm.ai_callable(desc="Turn on/off the lights in a room")
    async def toggle_light(
        self,
        room: Annotated[Room, llm.TypeInfo(desc="The specific room")],
        status: bool,
    ):
        logging.info("toggle_light %s %s", room, status)
        ctx = AssistantContext.get_current()
        key = "enabled_rooms" if status else "disabled_rooms"
        li = ctx.get_metadata(key, [])
        li.append(room)
        ctx.store_metadata(key, li)

    @llm.ai_callable(desc="User want the assistant to stop/pause speaking")
    def stop_speaking(self):
        pass  # do nothing


async def entrypoint(ctx: JobContext):
    gpt = openai.LLM(model="gpt-4-turbo")

    initial_ctx = llm.ChatContext(
        messages=[
            llm.ChatMessage(
                role=llm.ChatRole.SYSTEM,
                text="You are a voice assistant created by LiveKit. Your interface with users will be voice. You should use short and concise responses, and avoiding usage of unpronouncable punctuation.",
            )
        ]
    )

    assistant = VoiceAssistant(
        vad=silero.VAD(),
        stt=deepgram.STT(),
        llm=gpt,
        tts=elevenlabs.TTS(),
        fnc_ctx=AssistantFnc(),
        chat_ctx=initial_ctx,
    )

    async def _answer_light_toggling(enabled_rooms, disabled_rooms):
        prompt = "Make a summary of the following actions you did:"
        if enabled_rooms:
            enabled_rooms_str = ", ".join(enabled_rooms)
            prompt += f"\n - You enabled the lights in the following rooms: {enabled_rooms_str}"

        if disabled_rooms:
            disabled_rooms_str = ", ".join(disabled_rooms)
            prompt += f"\n - You disabled the lights in the following rooms {disabled_rooms_str}"

        chat_ctx = llm.ChatContext(
            messages=[llm.ChatMessage(role=llm.ChatRole.SYSTEM, text=prompt)]
        )

        stream = await gpt.chat(chat_ctx)
        await assistant.say(stream)

    @assistant.on("agent_speech_interrupted")
    def _agent_speech_interrupted(chat_ctx: llm.ChatContext, msg: llm.ChatMessage):
        msg.text += "... (user interrupted you)"

    @assistant.on("function_calls_finished")
    def _function_calls_done(ctx: AssistantContext):
        logging.info("function_calls_done %s", ctx)
        enabled_rooms = ctx.get_metadata("enabled_rooms", [])
        disabled_rooms = ctx.get_metadata("disabled_rooms", [])

        if enabled_rooms or disabled_rooms:
            # if there was a change in the lights, summarize it and let the user know
            asyncio.ensure_future(_answer_light_toggling(enabled_rooms, disabled_rooms))

    assistant.start(ctx.room)
    await asyncio.sleep(3)
    await assistant.say("Hey, how can I help you today?")


async def request_fnc(req: JobRequest) -> None:
    logging.info("received request %s", req)
    await req.accept(entrypoint)


if __name__ == "__main__":
    cli.run_app(WorkerOptions(request_fnc))

remix_and_resample effect optimization


                if isinstance(data, rtc.AudioFrame):
                    # TODO(theomonnom): The remix_and_resample method is low quality
                    # and should be replaced with a continuous resampling
                    frame = data.remix_and_resample(
                        self._sample_rate, self._num_channels
                    )

When will this TODO be optimized? After testing, the accuracy of this solution is much different from that of using pyaudio to read data from the microphone.

Bug in the examples/kitt

After the latest updates, the example agent KITT does not run

Exception in inference 'SynthesizeStream' object has no attribute 'flush'
Traceback (most recent call last):
  File "examples/kitt/inference_job.py", line 111, in _run
    await asyncio.gather(
  File "examples/kitt/inference_job.py", line 132, in _llm_task
    await self._tts_stream.flush()
          ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'SynthesizeStream' object has no attribute 'flush'

Agent speech output audio is interpreted as user speech

When using LiveKit agents, sometimes the agent hears its own TTS output (eg via the laptop speakers) which is then interpreted as speech from the user.

This then creates a feedback loop where the agent will then translate + respond a second time to its own speech output.

This only seems to happen when device volume is above ~25-30% and audio is being played through the device speakers.

To provide a seamless UX though, the user shouldn't have to worry about managing volume level in order to prevent this.

My current approach is:

  1. When instantiating a LiveKit room, enabling audioSuppression and echoCancellation, eg:
    <LiveKitRoom
        token={createAudioCoachingCallRequest.result.room_access_token}
        serverUrl={createAudioCoachingCallRequest.result.active_server_websocket_url}
        audio={{echoCancellation: true, noiseSuppression: true}}
        connect={true}
    >
  1. Enabling allowInterruptions=True in agent.py, eg:
    assistant = VoiceAssistant(
        ...,
        allow_interruptions=True,
    )
  1. Muting the user's mic on user_speech_committed + agent_started_speaking events, then unmuting on agent_speech_committed event (eg, after the Agent finishes speaking).

Muting the user's mic is a short-term workaround -- the main limitation being that the user can't interrupt the agent once it starts speaking.

Are there best practices for preventing this feedback loop / is this something LiveKit is working on addressing?

TTS Steaming is Broken for livekit-plugins-elevenlabs v0.4.0

This is a more clear description + RCA of #279

I think the issue is related to the TTS streaming implementation of livekit-plugins-elevenlabs. The reason I think that is because when I comment out this code from the assistant.py code, the very first assistant.say call is sent down to the agent playground.

Debugging further, I was able to verify that OpenAI is sending down the correct response to voices, but it wasn't getting streamed as audio to the playground.

I also tried downgrading to all the 0.4.0 dev versions, and none of them fixed the issue. 0.3.0 didn't work at all with the other packages.

The product code I'm using is the official agents quickstart guide.

Quickstart on the doc doesn't work. "Waiting for audio track" forever

I was trying to learn the agent but even the quickstart on the documentation doesn't work. I have properly set the steps and also set up deepgram api key. The agent playground works and I was able to join the room and Agent connected true but status is "starting" forever and in audio section, "Waiting for audio track" forever. I'm using Mac M3 with chrome.
Please help me out. Thanks in advance.

OpenAI: Optional arguments for ai.callable results in Key Error

When using an optional parameter with @llm.ai_callable, an "Key Error: 'key'" is thrown at https://github.com/livekit/agents/blob/main/livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/llm.py#L169

@llm.ai_callable(desc="Use this tool to find a flight.")
async def search_flights(
    self,
    departure_id: Annotated[str, llm.TypeInfo(desc="Departure airport's IATA code or a city's Freebase ID starting with.")],
    passengers: Annotated[str, llm.TypeInfo(desc="Number of passenger to book the ticket for.")] = "1"
):

This happens because the args do not contain the "passenger" argument. Using arg.default it would be possible to populate the default values beforehand.

fnc = fncs[name]
# validate args before calling fnc
for arg in fnc.args.values():
    # Populate args with default values
    if arg.name not in args and arg.default is not inspect.Parameter.empty:
        args[arg.name] = arg.default

    if arg.default is inspect.Parameter.empty and arg.name not in args:
        logger.error(f"missing required arg {arg.name} for ai_callable {name}")
        return
  • Affected version livekit-plugins-openai~=0.4.dev1

Duplicated agent responses (LLM inference + TTS audio)

I've noticed that occasionally the agent will generate two distinct responses (LLM inference and TTS audio) for the same user input.

Interestingly, the second LLM inference isn't generated until after the first TTS audio is completed.

Usually, the second LLM inference + response will be generated using the entire user input, with the first inference being generated using a fraction of it (eg, it doesn't always seem to wait for the user to finish, or handle an interruption cleanly).

Another variant of this I've seen is that sometimes the LLM inference seems to get "caught" - eg, the AI will respond to the previous question I asked instead of the current one, but only once I ask the following question.

Will add logs here as repro's happen locally.

Am using this local setup on Macbook Chrome:

    assistant = VoiceAssistant(
        vad=silero.VAD(),
        stt=deepgram.STT(),
        llm=openai.LLM(model="gpt-4o"),
        tts=elevenlabs.TTS(voice=DEFAULT_VOICE),
        chat_ctx=initial_ctx,
        fnc_ctx=fnc_ctx,
        allow_interruptions=True,
        debug=True
    )

Ability to perform actions when the session ends

Discussion from Slack:


I'm experimenting with the transcription agent example. It works well, but I'd like to do a bit of post processing after the room ends. I can't figure out where to do this though. It seems like the agent worker is possibly being killed immediately.
I've tried listening on the 'disconnect' event in my agent like this:

@job.room.on("disconnected")
async def on_room_disconnect():
    print('disconnected, do work here?')  # this never runs

We should ensure that all disconnected callbacks are finished before we terminate the worker process.

STT Timing Information -> Propose emitting END_OF_SPEECH before FINAL_TRANSCRIPT

I'm having trouble capturing timing information with VAD + STT.

given:

openai_stt = openai.STT()
vad = silero.VAD()
vad_stream = vad.stream()
stt = StreamAdapter(openai_stt, vad_stream)
stt_stream = stt.stream()

I looked into the StreamAdapter and found that it was re-emitting the VAD start/end of speech events. I was planning to use those to capture timing, but then I found that the END_OF_SPEECH event is delayed until after the FINAL_TRANSCRIPT, meaning that the timing now includes inference and API call overhead.

It looks like the END_OF_SPEECH event includes the first alternative just for convenience. I would propose to propagate the VAD events as-is in the adapter, and direct user to the transcript events to get transcription results.

diff --git a/livekit-agents/livekit/agents/stt/stream_adapter.py b/livekit-agents/livekit/agents/stt/stream_adapter.py
index 7050178..9b2d918 100644
--- a/livekit-agents/livekit/agents/stt/stream_adapter.py
+++ b/livekit-agents/livekit/agents/stt/stream_adapter.py
@@ -76,6 +76,9 @@ class StreamAdapterWrapper(SpeechStream):
                     start_event = SpeechEvent(SpeechEventType.START_OF_SPEECH)
                     self._event_queue.put_nowait(start_event)
                 elif event.type == VADEventType.END_OF_SPEECH:
+                    end_event = SpeechEvent(type=SpeechEventType.END_OF_SPEECH)
+                    self._event_queue.put_nowait(end_event)
+
                     merged_frames = merge_frames(event.frames)
                     event = await self._stt.recognize(
                         buffer=merged_frames, *self._args, **self._kwargs
@@ -87,12 +90,6 @@ class StreamAdapterWrapper(SpeechStream):
                         alternatives=[event.alternatives[0]],
                     )
                     self._event_queue.put_nowait(final_event)
-
-                    end_event = SpeechEvent(
-                        type=SpeechEventType.END_OF_SPEECH,
-                        alternatives=[event.alternatives[0]],
-                    )
-                    self._event_queue.put_nowait(end_event)
         except Exception:
             logging.exception("stt stream adapter failed")
         finally:

agent architecture - recovery from agent shutdown

if an agent (implemented by users of livekit using the python sdk) crashes, then ideally the livekit-backend should continue pinging the agent pool until another agent becomes available.

however this is not the case:
if the agent stops (for instance I am running the agent in my debugger, and stop the debugger to change code),
and then run the agent again, the livekit-backend never calls my agent to rejoin the room.

for a system built with agents to become production-ready, this error recovery mechanism is a must

deepgram connection failed

Has anyone encountered this problem?

{"asctime": "2024-05-20 20:00:29,659", "level": "WARNING", "name": "livekit.plugins.deepgram", "message": "deepgram connection failed, retrying in 2s", "job_id": "AJ_oRch8GR9fxqf", "pid": 99836}

{"asctime": "2024-05-20 20:00:31,663", "level": "INFO", "name": "livekit.plugins.deepgram", "message": "connecting to deepgram url wss://api.deepgram.com/v1/listen?model=nova-2-general&punctuate=true&smart_format=true&interim_results=true&encoding=linear16&sample_rate=48000&vad_events=true&channels=1&endpointing=0&language=en-us", "job_id": "AJ_oRch8GR9fxqf", "pid": 99836}

{"asctime": "2024-05-20 20:00:29,662", "level": "ERROR", "name": "livekit.plugins.deepgram", "message": "deepgram Exception.with_tracebackTraceback (most recent call last):\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/connector.py\", line 1025, in _wrap_create_connection\n return await self._loop.create_connection(*args, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/asyncio/base_events.py\", line 1085, in create_connection\n raise exceptions[0]\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/asyncio/base_events.py\", line 1069, in create_connection\n sock = await self._connect_sock(\n ^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/asyncio/base_events.py\", line 973, in _connect_sock\n await self.sock_connect(sock, address)\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/asyncio/selector_events.py\", line 634, in sock_connect\n return await fut\n ^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/asyncio/selector_events.py\", line 674, in _sock_connect_cb\n raise OSError(err, f'Connect call failed {address}')\nTimeoutError: [Errno 60] Connect call failed ('38.104.135.211', 443)\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/livekit/plugins/deepgram/stt.py\", line 228, in _run\n ws = await self._session.ws_connect(url, headers=headers)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/client.py\", line 835, in _ws_connect\n resp = await self.request(\n ^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/client.py\", line 581, in _request\n conn = await self._connector.connect(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/connector.py\", line 544, in connect\n proto = await self._create_connection(req, traces, timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/connector.py\", line 944, in _create_connection\n _, proto = await self._create_direct_connection(req, traces, timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/connector.py\", line 1257, in _create_direct_connection\n raise last_exc\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/connector.py\", line 1226, in _create_direct_connection\n transp, proto = await self._wrap_create_connection(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/aiohttp/connector.py\", line 1033, in _wrap_create_connection\n raise client_error(req.connection_key, exc) from exc\naiohttp.client_exceptions.ClientConnectorError: Cannot connect to host api.deepgram.com:443 ssl:default [Connect call failed ('38.104.135.211', 443)]\n", "job_id": "AJ_oRch8GR9fxqf", "pid": 99836}

livekit is not support CentOS 7?

I want to start livekit-agents
I used livekit-cloud.
But I meet this error.

OSError: /home/shared/apps/tutor-livekit-speech/.venv/lib/python3.12/site-packages/livekit/rtc/resources/liblivekit_ffi.so: cannot open shared object file: No such file or directory

system:
Linux version 4.19.104-300.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)) livekit/livekit#1 SMP Mon Feb 17 15:34:16 UTC 2020
CentOS Linux release 7.6.1810 (Core)

version:
livekit: 0.11.1
livekit-agents:0.6.0

language:
python3.12

OnDemand Agent

A use case we're exploring involves implementing a translator agent that would only be needed when participants are speaking different languages. It seems that an on-demand agent would be better suited than agents automatically joining the room since the translator agent wouldn't always be needed. We envision user interaction that allows for starting and stopping the agent as needed. Other than running "python my_agent.py simulate-job --room-name ", are there any other approaches for this or anything the team considering?

Minimal Assistant Download Files error

I get the following onnx error when trying to download files. Please help

➜ python minimal_assistant.py download-files
Using cache found in /Users/sajjadk/.cache/torch/hub/snakers4_silero-vad_master
Traceback (most recent call last):
File "/Users/sajjadk/dev/onset_assist/agents/examples/voice-assistant/minimal_assistant.py", line 43, in
cli.run_app(WorkerOptions(request_fnc))
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/livekit/agents/cli/cli.py", line 127, in run_app
cli()
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/click/core.py", line 1157, in call
return self.main(*args, **kwargs)
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/livekit/agents/cli/cli.py", line 124, in download_files
plugin.download_files()
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/livekit/plugins/silero/init.py", line 29, in download_files
_ = torch.hub.load(
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/torch/hub.py", line 568, in load
model = _load_local(repo_or_dir, model, *args, **kwargs)
File "/Users/sajjadk/dev/onset_assist/agents/myenv/lib/python3.10/site-packages/torch/hub.py", line 597, in _load_local
model = entry(*args, **kwargs)
TypeError: silero_vad() got an unexpected keyword argument 'use_onnx'

In Kitt example, eleven labs API throws many time out errors

What I expect

When Running the agent I see logs but no errors

What happens

The repeated error you get while the agent is running:

ERROR:root:Unhandled message from ElevenLabs: {'message': 'Have not received a new text input within the timeout of 20.0 seconds. Streaming input terminated. Please make sure to either feed the input in the timely manner, or to send the end of input text (empty string "") when done.', 'error': 'input_timeout_exceeded', 'code': 1008}

How to reproduce

Follow the steps to run the kitt example and open her up in the playground.

Severity

This error happens repeatedly and even after a few seconds of this failure on an unpaid eleven labs account a free account will get banned with this error response:

ERROR:root:Unhandled message from ElevenLabs: {'message': 'Unusual activity detected. Free Tier usage disabled. If you are using 
a proxy/VPN you might need to purchase a Paid Plan to not trigger our abuse detectors. Free Tier only works if users do not abuse it, for example by creating multiple free accounts. If we notice that many people try to abuse it, we will need to reconsider Free Tier altogether. \nPlease play fair and purchase any Paid Subscription to continue.', 'error': 'detected_unusual_activity', 'code': 1008}

Eleven Labs TTS Stream Doesn't return the text of the audio events being generated

Just add this code to fix it please

          text = ''
          try:
              text = ''.join(msg['normalizedAlignment']['chars'])
          except Exception:
              pass

In this section of the code
env/lib/python3.10/site-packages/livekit/plugins/elevenlabs/tts.py

LINE 286: msg = json.loads(msg.data)
if msg.get("audio"):
    data = base64.b64decode(msg["audio"])
    audio_frame = rtc.AudioFrame(
        data=data,
        sample_rate=self._config.sample_rate,
        num_channels=1,
        samples_per_channel=len(data) // 2,
    )
    text = ''
    try:
        text = ''.join(msg['normalizedAlignment']['chars'])
    except Exception:
        pass
    self._event_queue.put_nowait(
        tts.SynthesisEvent(
            type=tts.SynthesisEventType.AUDIO,
            audio=tts.SynthesizedAudio(text=text, data=audio_frame),
        )
    )

what is the working version of example/kitt

I am trying to local deploy the example/kitt on branch neil/kitt, but it fails to work, the agent can join in the room, but when llm replies the text, the agent is not speaking. The log shows below, looks tts is not called in the process. Is the latest example/kitt working on branch neil/kitt? I know there are many changes in the kitt area. How can I get the working example kitt working? Thanks.
image
Uploading image (1).png…

livekit is not support CentOS 7?

I want to start livekit-agents
I used livekit-cloud.
I start this:
python3 main.py download-files
But I meet this error.

OSError: /home/shared/apps/tutor-livekit-speech/.venv/lib/python3.12/site-packages/livekit/rtc/resources/liblivekit_ffi.so: cannot open shared object file: No such file or directory

system:
Linux version 4.19.104-300.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)) #1 SMP Mon Feb 17 15:34:16 UTC 2020
CentOS Linux release 7.6.1810 (Core)

version:
livekit: 0.11.1
livekit-agents:0.6.0

language:
python3.12

wait_pc_connection error job_request.accept

I am testing agents and everything has been working fine until today when I started getting wait_pc_connection error thrown in the async def job_request_cb(job_request: agents.JobRequest):
await job_request.accept(

I am also seeing this in the logs, which I am not sure if is related:

2024-04-12 11:09:44,964 - ERROR - livekit_api::signal_client::signal_stream:171:livekit_api::signal_client::signal_stream - unhandled websocket message Err(Protocol(ResetWithoutClosingHandshake))
2024-04-12 11:09:44,965 - DEBUG - livekit::rtc_engine::rtc_session:455:livekit::rtc_engine::rtc_session - received leave request: LeaveRequest { can_reconnect: false, reason: DuplicateIdentity }

I tried upgrading all the of the livekit python libraries but no luck.

Any ideas?

Audio was attempted to be pushed after the stream was closed.

Hi there! 👋

I ran into a little hiccup while working on the voice assistant.

It seems like there is an issue in livekit/agents/transcription/tts_forwarder.py.

Here is the error message :

Task exception was never retrieved
future: <Task finished name='Task-17356' coro=<VoiceAssistant._synthesize_streamed_speech_co.<locals>._read_generated_audio_task() done, defined at /Users/ubeytdemir/anaconda3/lib/python3.11/site-packages/livekit/agents/voice_assistant/assistant.py:755> exception=RuntimeError('push_audio called after close')>
Traceback (most recent call last):
  File "/Users/ubeytdemir/anaconda3/lib/python3.11/site-packages/livekit/agents/voice_assistant/assistant.py", line 766, in _read_generated_audio_task
    tts_forwarder.push_audio(event.audio.data)
  File "/Users/ubeytdemir/anaconda3/lib/python3.11/site-packages/livekit/agents/transcription/tts_forwarder.py", line 148, in push_audio
    raise RuntimeError("push_audio called after close")
RuntimeError: push_audio called after close

TTS plugin : 11Labs
Python Version : 3.11.5
OS: Darwin arm64

AttributeError on docker run: 'livekit.rtc' has no attribute 'ArgbFrame'

I executed docker build and run as follows.

docker build fal ./examples/fal
docker run fal

Then, the following error occurred.

Traceback (most recent call last):
  File "/app/fal.py", line 21, in <module>
    from fal_sd_turbo import FalSDTurbo
  File "/app/fal_sd_turbo.py", line 61, in <module>
    class SDTurboHighFPSStream:
  File "/app/fal_sd_turbo.py", line 201, in SDTurboHighFPSStream
    async def __anext__(self) -> rtc.ArgbFrame:
                                 ^^^^^^^^^^^^^
AttributeError: module 'livekit.rtc' has no attribute 'ArgbFrame'

I would appreciate it if you could tell me how to handle this error.

Thank you.

wait_pc_connection time out

I meet some error.
the pc_connection is always time out.(maybe my free account?)

@davidzhao
@JARVISMindEngineer

need some help please.

2024-06-05 16:05:05,356 - livekit - ERROR - livekit_ffi::server::room:200:livekit_ffi::server::room - error while connecting to a room: engine: connection error: wait_pc_connection timed out 2024-06-05 16:05:05,356 - livekit.agents - DEBUG - disconnecting from room 2024-06-05 16:05:05,356 - livekit - ERROR - livekit_ffi::server::room:200:livekit_ffi::server::room - error while connecting to a room: engine: connection error: wait_pc_connection timed out {"asctime": "2024-06-05 16:05:05,356", "level": "ERROR", "name": "livekit", "message": "livekit_ffi::server::room:200:livekit_ffi::server::room - error while connecting to a room: engine: connection error: wait_pc_connection timed out", "taskName": "Task-13", "job_id": "AJ_6eR7aeYjj2QR", "pid": 22306} 2024-06-05 16:05:05,608 - livekit.agents - ERROR - pipe closed, exiting job {"asctime": "2024-06-05 16:05:05,608", "level": "ERROR", "name": "livekit.agents", "message": "pipe closed, exiting job", "taskName": "Task-13", "job_id": "AJ_6eR7aeYjj2QR", "pid": 22306} 2024-06-05 16:05:05,608 - livekit.agents - INFO - job process closed {"asctime": "2024-06-05 16:05:05,608", "level": "INFO", "name": "livekit.agents", "message": "job process closed", "taskName": "Task-13", "job_id": "AJ_6eR7aeYjj2QR", "pid": 22306}

and sometimes other error
`2024-06-05 17:20:50,914 - livekit.agents - WARNING - assignment for job AJ_4UiBnp38bMBp timed out
{"asctime": "2024-06-05 17:20:50,914", "level": "WARNING", "name": "livekit.agents", "message": "assignment for job AJ_4UiBnp38bMBp timed out", "taskName": "Task-65", "req": "<livekit.agents.job_request.JobRequest object at 0x151d76780>"}
2024-06-05 17:20:50,915 - livekit.agents - ERROR - user request handler for job AJ_4UiBnp38bMBp failed
Traceback (most recent call last):
File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
return await fut
^^^^^^^^^
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/Users/yangqingyuan/venv/lib/python3.12/site-packages/livekit/agents/worker.py", line 386, in _user_cb
await self._opts.request_fnc(req)
File "/Users/yangqingyuan/PycharmProjects/livekit/main.py", line 65, in request_fnc
await req.accept(entrypoint)
File "/Users/yangqingyuan/venv/lib/python3.12/site-packages/livekit/agents/job_request.py", line 127, in accept
raise exc
File "/Users/yangqingyuan/venv/lib/python3.12/site-packages/livekit/agents/worker.py", line 429, in _wait_response
await asyncio.wait_for(wait_assignment, consts.ASSIGNMENT_TIMEOUT)
File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 519, in wait_for
async with timeouts.timeout(timeout):
File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/timeouts.py", line 115, in aexit
raise TimeoutError from exc_val
TimeoutError
{"asctime": "2024-06-05 17:20:50,915", "level": "ERROR", "name": "livekit.agents", "message": "user request handler for job AJ_4UiBnp38bMBp failed", "exc_info": "Traceback (most recent call last):\n File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 520, in wait_for\n return await fut\n ^^^^^^^^^\nasyncio.exceptions.CancelledError\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File "/Users/yangqingyuan/venv/lib/python3.12/site-packages/livekit/agents/worker.py", line 386, in _user_cb\n await self._opts.request_fnc(req)\n File "/Users/yangqingyuan/PycharmProjects/livekit/main.py", line 65, in request_fnc\n await req.accept(entrypoint)\n File "/Users/yangqingyuan/venv/lib/python3.12/site-packages/livekit/agents/job_request.py", line 127, in accept\n raise exc\n File "/Users/yangqingyuan/venv/lib/python3.12/site-packages/livekit/agents/worker.py", line 429, in _wait_response\n await asyncio.wait_for(wait_assignment, consts.ASSIGNMENT_TIMEOUT)\n File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/tasks.py", line 519, in wait_for\n async with timeouts.timeout(timeout):\n File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/asyncio/timeouts.py", line 115, in aexit\n raise TimeoutError from exc_val\nTimeoutError", "taskName": "Task-66", "req": "<livekit.agents.job_request.JobRequest object at 0x151d76780>"}`

VADEventType error

When I was running the worker locally, I encountered an issue where it was impossible to conduct agent conversations. After debugging, it was discovered that within the "silero/vad.py" file, the method "_dispatch_event" consistently failed to create "agents.vad.VADEvent".

Subsequently, the issue was identified to be related to the VADEventType, as illustrated in the figure.
wait for help @davidzhao

问题图1
image
image

My playground is not voice and can't talk with agent #293

I successfully deployed the worker locally and registered it using ElevenLabs, but after a successful connection, there is no voice saying "Hey, how can I help you today?".

I talk with agent, there is not response and voice. And I didn't find some error log.

image

this is my log:

import sys; print('Python %s on %s' % (sys.version, sys.platform)) /Users/yangqingyuan/anaconda3/bin/python -X pycache_prefix=/Users/yangqingyuan/Library/Caches/JetBrains/PyCharm2024.1/cpython-cache /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd.py --multiprocess --qt-support=auto --client 127.0.0.1 --port 61578 --file /Users/yangqingyuan/main.py start Connected to pydev debugger (build 241.15989.155) {"asctime": "2024-05-20 17:55:01,480", "level": "INFO", "name": "livekit.agents", "message": "starting worker", "version": "0.6.0"} {"asctime": "2024-05-20 17:55:04,062", "level": "INFO", "name": "livekit.agents", "message": "registered worker", "id": "AW_3947XPhMbsS8", "server_info": "edition: Cloud\nversion: \"1.6.1\"\nprotocol: 13\nregion: \"Japan\"\nnode_id: \"NC_OTOKYO1A_a23my2USzTK5\"\n"} {"asctime": "2024-05-20 17:55:13,499", "level": "INFO", "name": "root", "message": "received request <livekit.agents.job_request.JobRequest object at 0x142008ad0>"} {"asctime": "2024-05-20 17:55:13,607", "level": "INFO", "name": "livekit.agents", "message": "accepted job AJ_nPJmwytXoBGM", "job": "id: \"AJ_nPJmwytXoBGM\"\nroom {\n sid: \"RM_PNHFgotZGwGc\"\n name: \"playground-rVeN-H9h0\"\n empty_timeout: 300\n creation_time: 1716198912\n enabled_codecs {\n mime: \"video/H264\"\n }\n enabled_codecs {\n mime: \"video/VP8\"\n }\n enabled_codecs {\n mime: \"video/VP9\"\n }\n enabled_codecs {\n mime: \"video/AV1\"\n }\n enabled_codecs {\n mime: \"audio/red\"\n }\n enabled_codecs {\n mime: \"audio/opus\"\n }\n version {\n unix_micro: 1716198912832897\n }\n departure_timeout: 20\n}\nnamespace: \"default\"\n"} {"asctime": "2024-05-20 17:55:22,110", "level": "INFO", "name": "livekit", "message": "livekit_ffi::server:125:livekit_ffi::server - initializing ffi server v0.5.0", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:22,113", "level": "INFO", "name": "livekit", "message": "livekit_ffi::cabi:27:livekit_ffi::cabi - initializing ffi server v0.5.0", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:22,125", "level": "INFO", "name": "livekit", "message": "livekit_api::signal_client::signal_stream:88:livekit_api::signal_client::signal_stream - connecting to wss://frogpig-iidj6sdo.livekit.cloud/rtc?sdk=rust&protocol=9&auto_subscribe=1&adaptive_stream=0&access_token=...", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} Using cache found in /Users/yangqingyuan/.cache/torch/hub/snakers4_silero-vad_master 2024-05-20 17:55:33.112970 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '628'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115145 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '629'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115185 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '623'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115194 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '625'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115204 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '620'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115500 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '139'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115529 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '131'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115535 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '140'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115541 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '134'. It is not used by any node and should be removed from the model. 2024-05-20 17:55:33.115546 [W:onnxruntime:, graph.cc:3593 CleanUnusedInitializersAndNodeArgs] Removing initializer '136'. It is not used by any node and should be removed from the model. {"asctime": "2024-05-20 17:55:33,517", "level": "WARNING", "name": "livekit.agents", "message": "Running <Task pending name='Task-16' coro=<entrypoint() running at /Users/yangqingyuan/main.py:43> wait_for=<Future pending cb=[Task.task_wakeup()]> cb=[_start.<locals>._start_if_valid.<locals>.log_exception() at /Users/yangqingyuan/anaconda3/lib/python3.11/site-packages/livekit/agents/ipc/job_main.py:99]> took too long: 2.36 seconds", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:36,517", "level": "INFO", "name": "livekit.agents", "message": "assistant - saying", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:36,518", "level": "INFO", "name": "livekit.agents", "message": "assistant - synthesizing text", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:36,519", "level": "INFO", "name": "livekit.agents", "message": "assistant - enqueuing speech", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:36,520", "level": "INFO", "name": "livekit.agents", "message": "assistant - speech validated, data=", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:36,527", "level": "INFO", "name": "livekit.agents", "message": "_SpeechData(source=<async_generator object VoiceAssistant.say.<locals>._gen at 0x134344d00>, allow_interruptions=True, add_to_ctx=True, val_ch=<livekit.agents.aio.channel.Chan object at 0x134303390>, validated=True, interrupted=True, collected_text='', answering_user_speech=None)", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:37,159", "level": "INFO", "name": "livekit.plugins.elevenlabs", "message": "waiting for 11labs message", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:37,991", "level": "INFO", "name": "livekit.plugins.elevenlabs", "message": "received 11labs message WSMessage(type=<WSMsgType.TEXT: 1>, data='{\"audio\":\"BAADAAQABgACAP///f/8//7//v///wAA///+///////+//3//f/+/wAAAAD///7//v8AAAAAAAAAAAAA//8AAAAAAAABAAEAAQABAAEAAQABAAEAAgABAAEAAQABAAEAAQACAAIAAgADAAMAAwADAAIAAwADAAIAAwADAAIAAwADAAMABAAEAAMAAwADAAMABAAEAAMAAwADAAMABAADAAMAAwADAAIAAQABAAEAAgABAAEAAQABAAIAAQAAAAEAAQAAAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgACAAIAAQABAP////8AAP////8AAAEAAQABAAEAAAAAAAAA//////////8AAAEAAQACAAEAAQABAAEAAQABAAIAAgABAAAAAQACAAIAAgACAAEAAQABAAAA/////wAAAQABAAIAAgABAAEAAQAAAAAAAAAAAP//AQACAAMABAACAAMAAwABAAEAAQACAAIAAQACAAIAAgACAAIAAQABAAAAAQAAAAAAAwADAAMAAwABAAEAAQAAAAEAAQABAAMABAADAAMAAwADAAIAAQABAAIAAgADAAYABwAGAAUAAwACAAEA//8BAAIAAwAEAAUABgAEAAIAAgACAAMAAwADAAIAAgADAAUABgAGAAYABQAFAAMAAgADAAUABQAFAAQABAAEAAQABAADAAIABAAEAAUABAACAAIAAQABAAEAAgAHAAoACgAJAAcABAACAAIAAQABAAQAAgABAAIAAQACAAMAAwAFAAYABAAFAAYAAwADAAEAAQADAAYACAAHAAgACAAFAAQAAwAEAAUABQAFAAgABwAFAAUAAgACAAQABQAGAAkABwAFAAUAAwADAAMAAQD+//7/AQAEAAYACAAIAAUABAABAP//AAABAAQACAAFAAMAAgD///7///8DAAUABwAHAAEA/v/9//7/BAAIAA0ADAAGAAQAAAD9//v//P/+/wAABAAFAAIAAQAAAP//AgADAAIABQAEAAQACQAGAAIAAAD+//7///8BAAgADgALAAUAAQD+//3////+//z//v8AAP///v8AAAMAAAD8//b/8//z//j///8CAAEABAACAP///P/3//z/AgADAAYAAQD5//z/AAADAAoADQAIAAIA///6//X/9P/3//v/AAAEAAEAAAAAAPz//P/3//P//f8JABMAIAAmAB4AEAABAPb/+v8NAB4AIwAfAA8A/v/t/93/2P/i/+v/9f8HAAYAAwAJAA0AGQAfABsAFAAOAA0ADwAVABIADQAIAP//9v/n/+H/5P/r/wAACQAKAAkAAwAFAAcACgAHAP3///8FABAAIQAlABwABADj/9H/0f/g/wMAIgAnAB4AEAD5/+v/5f/b/+D/7v/0//n//P8FAAoABAACAPr/8v/2/+z/6f/7////BgAUABMAFAABAO//5f/i//L/8//v/+//8P/5//X/8v/7/wYABgAGAAkA+P/t/+z/5v/p/+7/9v/7//3/AQD0/+f/9P/6/+3/6f/n/+//AgAEAA8AHgAfACQAJgAbAAEA4f/O/8T/yv/k//r/CQAGAPT/5v/o//T//f8IAAwAEQANAAUACgALAAwACwD8/+n/7/8DAAQA+P/e/9P/1//C/8T/5v8UAEUAUwBKACUA+f/y//7/IgAxABYA/v/d/9D/4//s//7/BQDg/7L/j/+G/7T/+v8tAD0AJQACAPX/CgAjACkAIgAPAAAA//8BAA4AFwAVABgADwD5/+z/6f/f/+D/9/8BAAgAHQASAAUADQDx/9b/1f/U//j/JgArACMABgDn/+b/5//m//X/FQAoAD0AYQBlAFEAEwDL/8X/y//z/0EAWwBJAAQAiv9G/0//kP8PAIYAvwDDAKIAYAAQANb/3f/y/+3/CAANABEAGgDq/9L/qf+H/5f/t/8JADEARQB7AFYACADe/8j/+v9EAGkAlwCuAKAAeQAKAJb/eP+U/7r/4/8OAAIAxP+o/8T/4v/5/yIAVwCbAKoAVgAAAM3/rv+t/+v/NQAqAEQASgD9/+v/sv+h//D/4P/a/zIAbgCOAL4AlQAoABEAAADt/zAAbwCXAIMAEQCv/0v/Iv+G/9b/wP+Y/5T/oP/a/wcABAAxADoADQAVAAwA+P83AI8AyADiAKYAJADP/7b/4v8aAAYA9P/V/3D/Qv9e/2b/2v9cACsAtv9a/5P/CwBEAG4AewB0AEwAQwBCAA8A9v8FAFYAawAkADUAIwDl/8n/pf+i/6H/v/8CAEAAZQANAI7/aP+K/w0AnwCcAE4ADwC6/6T/s//X/yoALAAQAOn/tf+6/9z/DgD7/+r/JQAhAB8AGQDv/ysALQAIAGEAywARAcEA1v8a/5j+fv5u/24AAQEaAUIAf/8A/8L+R/8aAN8AIQHuAIQA5f/N/97/zf87ABIAd/+p/9H/4P8jABAAJQBcAEoAMgDo/+D/9//R/xEAfADoAD4BWQG8AJn/sv7h/Qv+r/72/nj/oP89/8r+nf4P/63/+v/HALEBpAFJAckABABJ/+f+Gf+U//P/BQDJ/03/DP/l/pD+rf4n/4f/i/9//8X/4v8kAJ0ADQFOAQ8B5AClAAkAU/8H//b/3ADDAJsAQQAPABYA9P8WALL/1f9kACoAfwAsAKb/+P+P/6D/cgABAWoBpwGvAe4ABwCV/1b/5/9gAB0AawC0AGIAfACSAIgAkwA/ANr/hP8V/7/+9P6M/97/sf/c/zMA5/+O/1f/4v/IAK4AuQDOAHwAbQC+/0f/4v79/V7+XP8bAMwA7gCOAFYAdgBcAGMAeQBcANIA4QCWAIUA7P/H/8n/nP/R/z3/5v7C/vr9qv5K/z//TwDMAGUA0/8T/0z/cQAVAXkB5AGQAQoBLwCJ/74A6QFDAVgAJQBa/8D+Nf9R//z/dgAFAFcAQgCF/wcAvgBdAAoA0P+H/77/MAC0AC4B/QAgAEj/a/4M/sz+2P+HAfoCDALwAOn/j/4N/4v/7v+wABIBfwEPAXoAs//2/g3/R/8m/wT/uP/H/wEAYQDI//j/vP+k/wQAUf+C/38ADgFgAX8AhP+O/0b/BP9s/9T/IgB8AKUA6gA0AIn+3v0M/SP9n/6X/yoBGwGB/5D+gv15/ioAFQEwAvEBlwE5AaT/Gf9H/2T/eABzAQMBnP84/g392Pz9/C79zf2J/uT/hQBxANj/H/9O/4r/QgEJA5sDcQS6AzICuwDK/mr+S/9PADYB8wB9AMj/WP4V/cP80/2f/rr/BgEwAaIBFgEdAP4AfQEDASIBYACe/04A8f/e/xwBOAENAUMBrAD4/y8AJwAGAOoA7wBPAHUAHwAlAGgA7/8/AA0AjP/s/4L/BQBaALz/XQAH/+b9iv8cAEcAcQHwAdABNwKqARcA2/9H/3f+Cv/1/j3/vv8+/w7/kv40/tb+7v6O/tT+uP6//n/+Zf4w/9v+8v5z/6n/EACyAIIB2QCI/6P+A/7g/bz+Pv+s/+EApP9j/pz+If7x/iMAHQHhAVMB2gAMADj/af93/9T/VQB6AIcAJACV/57+lP6N/zoAHQE8AesA8AAwAWIBkgBeAKcAFAEzAjQCHAIbAosBwwFFAVsA1ABiAOT/QwGuABAACgG8/8j+3/4O/7sAlgFHAlsCtQBEAI3/rP9xAZkBVQHRAPv/tv9l/2X/3P8VAHcAigAoADMAfv9j/4UAQQAd/+r+ev+e/8//RwATAG4AqQAw/+T+7/9CAGkB2AKiAsQBMwBV/t38J/xv/Ij7z/vR/Jn8Wvwp+1z7sfsq/L39WP7T//f/+v4Z/+b+dP+X/6j/fQDi/0j/3f4F/rv9ef3Z/er+F//M/nL/T/8i/ycAJABCALsAaACj/2IAOwIxAoQBWQHPAVMCCAI1AQkBIAHkAEICZgP4A7cE0gQeBT4E5wNzBBsETQW5Bj8HNwclBogEqgIwAjsC/AILBYMFLgXGBB0D/QEAAt4CBAToA6cDiwP5AgMDlwM5BBkErgJpAUYARv9g/2v/Y/9K/3r9cfwX/J36Rvui+6X6G/uJ+rf5Qvnl+Pr5YPou+jr5tfie+dX44vdV+Lr4Vvhg9+L2QPdn9+T3efgP+NL3uvYL9zP5y/lV+0T9sv3I/bX7Bvpn+0D84f2AAGkA6P/n/6f9pvzV/Xr95v5NArYCOgJcAhkBMAD0AOQBkgNMBoUGzwVwBg8HcwfuBwAJqAmeC0cMUQqHCskKuQphCywLqwu7DLsMlAz6DKMMYwybDMgLGgwMDQENGw0UDEMKmgn5CPoHrwdfBxkHwwaLBQsEiwPCAQAAGQHa//b9A/4B/oP/KAA5/7P9R/td+ib5RPfv9qH1n/SZ89bwQ+8X7j3tXu1I7Zbsge2X777wEvLD8Zbwa/CY8IbwLvH+8m3zu/PW82zxR/CO8DDwQ/FJ8ozzUvRe9DP1T/W49rb3A/qh/eP+sAF0AjMB5QGJAoUF9wecB/UITgojCxILyQlQCuMLvg34Dp0PPhDcDwEQ5xHqEgcThhPhE9wVmhaCFY8V5xTaFFgVwxS+E2YSERElEeQRUhCTDx0Pjw14DXEMXQvCCtUJ9QkzCSoHCAYTBYAEHgXmA/wBVAGI/8/9dfzO+sv5rfij96z1DfNf8VfvVe3I7ETsaetb6/nq5em86PHmwOWH5aTkteTA5wXqi+mB6gHqDegx6Mnnuuef57PmiubW5gnn/ufH6QLrjexq7srw2/V9+B77JQDx/8kBpAXWBNYHYgwcDT4QtRApDnUNIAq9B8oGwAfxCvILwQ0YD5IMWwlgCR8NsBMjGjkdph+oHu4a7holG50ckiDlIqEiGiAvG60VWRMpE/EUuhfnFxcWmRIbDl0KpggFCgUMVQ5ZEBMPngw6CZIFLwRUA0YDVQOwAX7/Svwg+Zn24vM48uLxKfHg7v3sFutn6Ajn3eUz5RPlgeOp40jkIOSN5YDlYuS34zXi+eB+4LLfGuBa4ezhveJR4lfgV9+N3tnc590x4UjlC+0Z9Zj5vP6/ApgC3gRgBpEGTAvfDkEStBUfFDASiQ/BCvAHQwYNBmYGfgZcB3gHjAiNCa4JDgz/DyET2xU/GdYbXx0eH2AgXCBaIVAh/h/tH7IdvRuzGjAYVhZ0FIITFxSeEzQSGxDSDYIM0Qu6DFQOJQ+TD+MOIw0MC2cJVgfOBb0EPwGY/X/6Uvct9qL1Q/RP8/Lxoe+T7enqLuju5l/l0uTa5dDlluas5/zmWOUA4xXgtd1n3e3dAd9+4BHgm95Y3YDbGNpR2bDYGtrU2o7dZ+Wt7F71eP2GArQHpQlBCoQM6w7/EfgUqBe+GHYWOhPhDvoKDwnRBK8C9wEJAIEBSQIBAzMFGAivC60NVA8fEUMT9RfOHGAfUiP3JNEiICIxH1IbEBuHG58cOR4fHUoa5BcjFA0RpQ+1Dp8PHRDcD0wP3g2bDSgOUg41Dq4M+wneBiwEtwGT/8L+2fyA+436h/gy9/j0vvKn8Z7v/+ym66bq9OoY6+3o3Oe95t/kiuQD5MDh89/t3vLcmdoe2bnX59YN2Una3thx2FfXzdSS1f3XAtyM5mH09f8CCEkN2A6GDtEOJhCrEF4ULRi4F/QYTRUZEIgMtgeNBPUArv1d/KH74vuB/igAnAI8BZEGsQl+DI8OIBIdFz8bXh+iIYAgXSCnHywdhxwuHcQcgh16HlUcQxsaG7oX0xTSEmANvgrXChgKnw3MEJYRkhEcDywLnQcuBQYDPAN9BG0EwANQAvT/zP2J/N75rPda9lX0pvS383XxifAB7kPs8uoW6YDnIuUk5DnhdNyv2mDXmdUw2VbY39Yd2FHSA9B001TT99VF2KfXJthq3BbpwfYmBHoTzxYmFjUWzA6fDbkSpBR9GVIeFhqsFMQNnQYOAwj/cv2++n/4dvnR+UP6+Pxy/3UBuARxBbAFtwikDCAS0xhZHh0hHCLmIDMd+htzG4EdOSJXIwQkpCGkHEUZNBS1D6AM9ArDC3oMLg76DZoM2AzzC8UKhwpOCTYGFQbSBZEFmgfDBucF6wQHA3YAfPyf+Qb3gvXb9aP1h/Ve9EbxF+5b6fLmi+fK5rXosug55APiwN1Q2MLWGta01snZMtp01tvTrdFIzzLROdNb0/7Wzt2p55P5YQ0JFjcdpCBtF+4UJBUYEXUYFCHWIGUihR48EYQIpgGy+VX19/Fu8Rnxp/Dw8/DzrPbY/fr+KQIJBt8FHwrlEIAWrBtmIcUjoCKRIuEfGh6RHyIgnCDMIGkfURziGuEY9hMlD9gJkgVABXcGsQc9ChQLAQuFChUIQwYNBPMDUAX6BFwG+AYJBqoG1wXYAnYBjv8g/cD+b/5o/GD92Pp3+EX3KPK98Cvx+e9E8EDu9uks5g/ied2E2onXBdVr087Q087mzDTOl9CD0brRns9+zljNaM/y2YruRgk8IUYuRS0bJYYYlBB2EokXDiKqLSgwRyuoH9wLMv3h9FHsi+yJ7gzuFfFF8P/un+988D30VPYG+iH/YQL9CyAVFRo5IiolISQ/JNAhGB96H9AhoSPRJdglayK3HWcYMBL+CukFRgOmAhAFiAeGCGkJqwmXBwsE8wAx/u7/6AQ0CE8Mygy6CS8I7QTzApkDEQMtA4MDUwOmA0cDSAIfADn9RfrF9gH0dfNr9LH0CfSo8J3qeeTT3mzZ6NWV1FDTVdJN0avNA8l3yuvKY8wz0EDNHc2qy/vJ7tID6EIJpCfpOGE7wCtWHJATZg/VGeUmATMnPHs3xCbDD9v6gO005nblMujK6RTt1Oxr6Y7oy+da6S3uy/Fq9rn92AbWEqgcliPtJ70niCbHJeMjsCNdJwEq7iySLXknxyAKGfwQZQrTBMEBagBCAtgDRAMlA+0CtQFh/zT7E/dj+Bb+/gXnDasRLRBYDG8I4gQ0BHEFoQeyCiUMZgoOCBsFnQGi/4D9Ef3r+9b6svol9wH0G/FT7X7q2+bM4Pvb+tfz017ST86IzDDOiMyXzSHOwsiQxq3HIsngy6jQ/Ncd5O4EyCbFMxQ+PzQjG34WdxMKE1snczRSObY8+iupEkb7COoT5EnhleZC7fns2PCK7Q3kCuM74VfiE+oH8Uj5qgURExYbgiFFJUMiYiKJIhEfeyEbJs0qsTK+NF4uCCQuGPoNFgewBE0D9gPrBzsIdgZjBEAAAf42/DD51/cc+VH+6AToCg8PSA7NC8gIZAUZBQcHWwo4D6ERLxE/D/sKfAgJBr0CWQGx/g7+F/8y/vT9DfwB9oPvRegD4FnceNo02czaJ9tD11rQcMqcxGnBbcS9yL3JOc0o0KrMJM+k0TnXSfKCFIsvGj5AOGAnIhYeEPEVWB39Lp874zqANKUd3wE87q3kguOx5qvsme6t7D7qBuUG37ve6t/T43Ps/vNp/ioJGRMuGj8cVR7eHOQcQCA2Iu8nAy+qM+E3OzXEKpIeoBExCoUHgQcCCo8L5gyPCgYGCgCW+br2Ifa99nn5GP6/AVgH3Av5C44MDgvzB1MHgAcECVAMQBB9E0gT9hF+Dt0IEwbQAhIA6gGhAycFjAYkA038aPMP7LznnOW+5R7jOeCL3CnYV9R9zibLp8dHx+PHj8XMxKLB+sLpyJHPl9ak3OjmdvurGhcyaDpQNRcjpBIzEDcX9SJ9M0Q9ODw1MewaQwDz66HiQOF35vTs+PA88JPpbOKp25zYV94K5U7r4PQd/QoG9g4/FAgYuBmiHQEgth+LIsMj/SmlMvU1hTSMLJAh/haCD90JYAfNB7MJVAx8C8IHnAK2/Rv6M/iu9zb6Nv/sA+8HnwhLCBkIfwf6B6wI1QkvC1MNLA6mDUUO2gwTDSIOvwzDDGAKpghmCHkGcQW8Ann+1vl29cjwCO6t64rm2uJN3UTWt9FMzl7M9svwyUPF1MGAv9y/4sPLxujJxc6M0WrUaOLL97kUCTWFPX43BSqpE+IMkBY0Ip8yZkNqQiQ2SiCWAhPse+Hc4vHlqe1L9Bfudega4SHWVNWF2ljfHOj28P737QH7CggRFxVWGQsccB26IPAiSCi/LkM17Dh2NLctQyS3GSsTCw9SCnQLWg71CzsMeAhaANz9kvpj96f3dPdd+p//DwSHBxoIZgfYBloGOgfVCTYMNw30DjsQdw9ZEJAQiA5XDmoOxw0RDuoNNQscCIYEjf8V++v2WvMx7mPrXOmq4/ffTNqA04LPdc3hy+7Jo8eawr7AssAww/7H38jHyynPvM8g1MHeWu5XDbowtz3IPY0yAxffClMSFhk5LcJEqUW+P6gtbgm+72jip92a5C7vCvXp84btW+E41TrPTtGC2DziNu2P9VD+EgjrDLIPuhX0Fh4abiEYIkMoRzFMN/U+P0FTOp4u1SLuFj8PWA1fDW0PExJvECsKAQM3+571tfPc8BbwDPN89ur9pQR8BscGnwR5AYcBHAVWCW8P1RPwE20T1xFzEIQQDhEgEXsRZRFuELsPXw1rCjIIWgM6/R34dPFd7cns4OpG6lToQeBF2GrRUsqAx1TJHMokygrMlcaXwPnAQcE9xMPMLNSi1WbcROFl51wDeyPLNOs+fzeTHBsR9RCWFpsrUzyOQ85BljA5FKf3+eVu4WPkxOyb8ivxqur136bWxc930cbawuEj7PD0p/lmA/EJ9A1pFGoalx46IkMmdijJLhk3fDyYPj06CzH0JRUcuxSFD+4Ngw64DU4LhgUR/e72yPOP8Yvyp/M/8/D2hPgO+gz+3/7mAOoCegRPB78KRA9REScTxhRCE9ETvhNYEjsTJhTjFQoX9RZkFB4PWAlMAsf8VvkI92j15PPp8OPpyONS3vzYjtez1MLRh8/YzKTMYMv6ygTLvMpWywPMf801zbbPvdU52fvd5uZU7dr/KyE2MeE3gjeSHyYQQhFJE4kiAzZVPWI6Gi0LFFv3quZb4srkc+8i+vT6RfUj6nPZ884OzyPWv+OA8Sj8kAToCX4LewwJD6kRgRn6IEckTCr1LhAyvDn3Ovs0FzAsJHkbyReCEqMSZBIDEZAOPQfe/Vz0KO4q7OHtGvIh9bH42/mH+Fv4fvbz9tL6FP/sBNYKTQ6zELgSURKXErsTbhNkFIgUWhR6FfUVhRYOFTMR9QxbB7wBkP0E+fH1DvS18BjtMOjg4Hvcz9pC2eLZctd11HrRjdBg0UHPu9L50jTV0dn41k/W7tPH1ErZtt+W50ToePA7AYEV0y4tNQwrRx8VDTcHwhGYG0kqhDb2NQUt9hc9/0vrquHZ51/xIvqtAH77au4e4rvXLNQ03LTnkvGB+8UCBwasCHYK2gz0EBEXqh59ITckaCe3K6YzMTklOZowFyawG7oTLRJKEcgQpxFpENsLqgOU+JzwwesO7aDxgfTd+F/5A/gD92P1mvXZ+Jz9owLoCAwN0A86EckPKQ/wD/sRnBVAF9MW4RWiFC4VYBVxE24PGwqlBNv/Lfxo+Bf1SvH97Q/rMOfb47TgTt7R3JDbRtiy1f7U6NIZ1VXYT9mS25zaW9ax0enR1dNk1lzfs+P85RDqb+lE77cGtB9KLrc0TiecEssG0AZKEsEgDjKXOis1siYwDRvxieR05V/si/v0BCUDL/qA6mTbXNIz1k/iVe2p+78DwwSHCPMGgwVyCcIPURe+HnolHydNK34xXzPhMhUvFyemHdIYHhTIEfYTfxQ7FFgQ0gek+5jx0ezQ65Dvi/OI9wH6gPlq+AL12PKG8y/2fvwjBDMLjA/SENYPzg2cDVsP+RG1FD8X7xf2F58XtxV+E4oPSAsoBx0DewE0/xP8b/m28x7t7+fs4SHeZt6W33rhyuJG3+jZaNYR1OrT19Y+2WnbRt/L3YDZJNc41FPURtrw3UTh1OfB5rnrewCdFuwomzI7J8gTWAfKASENWR6HL6Q7ujk8LTsS5/bX5s7jHO9X/v8I1wtjA6Px8t8Y1NjS8d0U7uv7MQaFCtgHNQQ6Adz/NQaoED0ZFiK1J8Ipuy0FL7cr/iddIg0e8BsXGrYZLxgIGFYWMREWCjsAH/g48/TxSPOW9Z73EvnG95/0gfLw8MDxd/VR+uP+xQVOCjQL+AvdCa4JDw1oEckV+Bd0GOEXoRbsFQAVThMsEUoN3wjbBAAC+/8z/PD4T/M97EDo5uKa4EXhAOFq4pzhw92q2TzW1dSM1lvZltwY3jHegNvJ1V3UW9Qs2Cfd2t/J4hvjLOOX6NH4+w8TJhcuxSX5FZMEa/5jC9obTyyWPjI8pi37GBr5cude57nwvQIUD8ERzgeQ84jgedHgz8rbxewo/B8HdQqxBdUAJ/xO+mwBPg24Fhgh2yXLJe4p6inWJ5MlDSEHHQUbExttGqIaMhufGPET8g1bAwT7H/dJ9Dz3RvnE+p37Gvih9Q/xC+8l8GXx9Pbp++sAngVoBiIG7QTPBE8HxwsBEf0UBhkOGkYZihjUE8wQFhAODqINTA2MCvIGswKO+w31jvBD7FjqA+rl6TbnkeQh4rPdVdx12cLWvtYH1wTaZtvo2xfc8NrE2avY/deu1svXYt4R5PblcOxd72n5ixe6JJYl9CQ6EZ0EhAkwE2sdUCzRNwoz1ykOGPj8YuzZ7mP3mQN1EhgQrQRL9nHgZdWH1yXhL/LZ/VAEaQVpAPb7zfY1+GX/OAv4GKAeEiGPHxweMCHGIskkziSaIgEhzR5FHK8aDBqOGGcXBBJ1CBIAHvk09+v4N/vW+4L6X/fL8WTtB+pU6kfvwPWW/HUASAGxAPn+vP6aAMAE1wuDEnQXMxq1GZoX7hWcFJUTJBXNFBsSbhBUC04HxQRY/877E/fp78TqHuYz46rk8uVT5QXlsuDI2unWTdN+08HWG9tn38bi/eFC2wLX9tPv03TbU+El5tPrResC6GTyqwVfGPkpfSgqGw4O9wJjCCgVcyJ1Mvw3WTLAI/UIvfKn6wDyVAHJDnYVpg44/jnqr9jv08na8OpS+nwEhAi9AmT7yPTh8Bn2eAJvDzoaUR+jHX4cXxz3GzccYR3JHtcfpiHAIC0eMBurGPMWfRTlEJQJGQO1/+P9d/1S/Rr7ffe+9Nrwk+7y7dnt1u/X8+D3Ivti/j79Gf0I/8T/RwbKDEQRphaLGCQZEhlmF1UVUBQwFd0VhhU2E8UOwwmoA3z+BPrs9XjzGu+b6+LnOOPy4crg3ODt4OPeMtu718TWhNWC1lfZStw331jgG9zk1kzWfdUD3H7ke+jJ7FvuYfTVBcAaSiK1IlsbqwnJBTgL7BSFJYAxYjdCMSIgxAs89RLuyfjpA9AQ2BiaD8L+u+zV2vnVE9+t7I37JwVtB7EC4vjy8a7uBPK8/+INExccHYkbvhexGOMYcBiTGtYcNh6BIDUhGx4uG4kZ3xaKFC0RfgrnBdwDagJNAqwAov3R+dD0TfCz7dXt+u/g8mn1Mfao9t72n/Zu9z/5bf2bAx4KRA/9EbwTaRRvFBgVRBUuFoIXJRgiGBEVuBHnDPYG9QKY/Tn6lvgg9Y3xVO0p6AHkSOLR4SPhruCY3R7Zp9dF17zXB9nm2qbbjNxY2+fWC9Z41YTYFuCF5XroQes67Zf2qg7kHEohySJMFMUH+An4D78ZbStkNegyRS3zGhwBwPXi9e39hg3nFeoUNwqh97PlTtn62nPm8vNLAY0GagO5/IvzGu1Q7mL2pANVES8Y2xgBFkQStRKlFNkWwBo3HnkgzyG1IDsdWRp+GEsXfxWoEnIO1Ao9CegGbASbADX8zvid9OvxKPGk8Ybz1vSZ9DLzCPM187vz7vZR+YT9tQO8B6YLdg08DscPtxFEFP8VVxeRF1kX9BUIEyQQYQwVCfQFuwGH/hP7yvUt8ZrsUudf5TLlJOTz5Ojiyt2I2TDXENZ31eHYzdhQ2wTf1dlC2NvWz9Ri2Vff4uJd5rzqF++X+scQkhxHHfsfURG8BhENQxAsHIItlzWSNHUtShmXAmP3qfe/ApIPYRk9GFwL2flk55Dbldy35qv0nAEWB90E1/pm74Hoe+jy8RIAsAyfE/AVyhNnD5cOWw5ZEEsWbBv4H0Mi5CADHTwZkBcmF0oWvhOhEAgOKw1tCywHZQJI/VL5wfbn9LT0bfXQ9U32ivW88yXztfKj87T2wPql/vABEgUHBrQHnQq4DPMQ8BPAFFwV9BMPE3AS2hBJEKYPog03CzgHxAEz/Pr2tPOz8QbxVO817d/qg+aq4pPcedjO1zXXB9lG28DbJdwX3cXW19GR00fSRNgJ4lbkMedj62Tn0ezwBXAS1RopJOwVyQvoDFYMqhZAJNEuIjVAMYUkAw9N/d77+gHjC5oXUxhsDwwD4vCs4ungr+XO8PX8lgIwAg/8tfKB6mrpyu6k+ccE1wwSEQ8Pwg0KDCgL6g7CEwMZAh5IIFIf/Bw1GrAYyxi4GbAYUhX3EkoQCg4DC/sFIQK7/Yj7pflL90n3XPXl9G306/KQ8uLxjPI59Cr3/vp8/rgA6gG1AqQEGwmmDagRxBM9EqYQow/5DroQShKNEhkS5A5ZCXEDX/2S+df4u/j++OT2U/GB60vmWeG23wrfot243jndE9zq2jzX8dVN1KTTTNUM2ejaDNxS4KHgMODT5B3nkfH4DKoZPRy0IIARggZGC/wNTBe9J9oxGDQVL3MePgmi/LP90gV0DzoZWRnfD4gB2O734SXhq+iW9KL/rgOgARn62u+t6JfnrO5X+fwFiQ3+DbkN1QkECM8JTQ1ZEz8ZNx6xH+wetxw7GscZ2xpOGxAZzxUAE90QKA+XDIsILQW2ARX+dvrT9lf2jPZt92v4afak8zrxHu+d76/zv/j//QUBzgDp/x8AIQOqBkgL5w9UEg8UIxO5ER4QuQ4ND1QOVQ7QDMsI5AQUAEz7c/iN9tXy2fCG73TswOtv6LfhDN2+2R7YRdn72fzZgdwg3NjXwdQx0sDSFtn83QPhqOaE5rTmUfISA+4P2RndHHoTFQ5VCycN6RiRI8MvUjSELnUiTA45AZIAiAanEfYZ3xqVEuoCLvJl5Y7jEuom9XX/4gP7Agv6G+/i58vlxOzR+L8D7AqDDVQLaQc1BgMGGQnLEBIXZxyKH/Ad1BoZGFAXSxgFGn4aLBmTF1UVxxHlDGEIdgRBAen+gvwV+376aPnb90v1e/Ks8Crvo+4S8Ofy6PbF+lb8i/zF/Ej9KQCjBWcKUg4FEV0QKg+rDpsOkhA3EjISgRD0DN0I7gN0ABH/Jf7a/GX64PUc7/nqu+ez5bHmuORB4nHf59t62c/WXdYG2FrZP9k02bDX69Ww2Abcqt0H5N7n7+dp9+oIjw9CGNkYmw0gDFAOQg5MGzYndC2eMjAspB3JDZ4DfgSRC4IUXRxkGyMTGwSY8k7oaeY+7SX3bQAVBM0BYPoF7hPouOcS7K/4RwJsBwELuwjnBVkE6wRlCAQO7hQJGaIbihsjGq0YeRhrGUIXTRYoFd0TSxTdEtcPZgxoCfwDbP52+zf5VPqX/Pf7y/rg+M30YPEi7x/v3PL69z381v2l/Sz96vyR/qYB8QUMC4QOfA//Do0NQQxgDUUOjg7+DtcMLwrBBngC+P6C/JD7uvoV+cL0YfDv6zrnDeWV4Rvgo+Az357ez9zX2YbXhdUj1BDVuNlI3KDdCuJf4mbhg+OC5PfwOwcPE9MYlRiDEHwLlwruDaEUrSGSLTYw+yzcH5APhgb+BnsLWBK+GdAZHhSoCKf5KO8w7Dnvr/bP/aEAiP8M+ZDw8epp6frsLPS7/NgCvQXIBrkECANiBKoHrwuMEQcX3RiQGlUaARhbGLoZqhh2F1IXNxbJFa4UohFODgMMBQkUA4j/oP2r+6z8LfxY+lr5ZPbW8gTwXe8q8rH1j/l7+2f6ZPru+gT8KP8sA9sHkgxEDmMNIwwCC2kMZQ5dDz8QFg9UDMEI2gTrALn+MP7L/O/7Ffl589runOru5jvlHuR84lXhduCv3e7ZMdm41wzWdthY2VHasd1k3uHe8OIH47fiB+vF+OcHdBKdFEwQxA6PDDUMpBH7FjAiqikRKyomYBlGDzcKpApID9IT4hU6FvoOqAO3+ZTxmvAv9Nn5TP4hAAH+XveX8Z7tee1s8dz35P4eA+YFtQX3A7AEGgZGCbANDhLWFeAXQxjhFj0WpBaoF7IXdBY5FhoVyxMtEfkNtwyeCqUHzwP5/x3+KP29+yz7tPpx+cX4kfYA9J7z7PSM94r53/pi+wT85P12/lwA3gMFBzsKhAsSC0IK3wqRC1IMeA3XDNELnwm9BskD8QB4//j9dvxR+lb2B/HB7G7qx+iQ6APo2+RF4Wne3dlH1mTYc9uc3QfgTd5k20XbNtu03GHhXeZM6pPvOPrNBJkJmQ1gD3UOxBAEEsURWhfcHd8hjySXItcb/BMYDzENvAyiDm0R3hBHDh8H5v3y9/DzPvWy91T79f5z/kn8RPfW83vy3vNr+dr9UgKaBroHwwfSCEIJhQrnDakQXhPWFcYWyRWiFa8WURW/FHETYBH4EX8QFQ7wCz4JNQffA9b/z/xV++v6ovqA+hr6U/nX93X1C/RC9JX1pfhH++78lP7H/nP/eQDDAegETAhbCwIN1w22Da8MowxxC5EKTgp+CMQHhQbzAx0CEf8R+zD4c/Xy8c7v/e0/7JTs7OoY58njzd/U3HncutzO3kbizOFV36/cPdqU2w7fh+He5cjr+euP7bPyFfgzA8YLtQ/fElUThxApEOsSixQJHIwgbyDdH5cXEhCvCxUJAApIDEoOiA2QCbgCW/so9qv0cfaC+Un++gDC/5H9dvmZ9j33GfrO/VoDSAhcCVcLuwqLCf8KIAwhD9kR0hQwFh8VvBSWE1USBxJEEd0PqQ9wDiQMEwr4Bw8GRwN0ATn/1fz9+7b6XPoT+nf5a/lY+LD39Pcw+LX5+Pt8/RL/sABaAVgCtQT0BWYGlgjDCXkJDQryCV0JxQnnCCEHawaIBLEBwv/T/Wz7D/n29qv0IvOB8WTuV+zH6XTmnOVA5K/ikOMs4/fhcOL04HLfXeFz4ifj9+VF5/vmQOpD7fjrFu3+7xj2RgDmB7MLcg35D+0PDw6NDjoQlBGzFigbOxilFk8SpQoICTwHUgVBCC8JjAfIBSgBifzi+Nr3Dfr0+7L/GAIPAv0B9/9A/63/RAFWBVQIdAsjDn4OTA8EEJsPBRCLEckSHBSYFGkUJBQpE4ERQQ6jDAoMtgoRCnkIXQcBBncDHQFu/jb8Kfsr+0X75/sG/Fr7wPv9+mj6xPv7/Jf+GgHGAvYCMANvA+UDCgbeB88IswqyCg8JgggxB0AGywV0BGYD1AGX/z39gPrs97z1qPO48rLxeO937Tfrn+hs5qDlm+VY5nbnlebg5QzlduKL4pfk1OWY6Pjqveo5667sX+tt7NDvQPCr9v//jgIXBgcK4QhAC3UNXQoODMwPABB+EpgTtQ9lDYUKaQYqBZYEEAXBBmsH9wYZBD0BNP42/Gf+aABnA1QH/QfsB8MHJgViBLgFhQcOC/8NGQ/4DnUP7g2QDMYNCg4+EP4RPxB6Dx8OqgvqC6ALigpbCmsJ3gfdBRMEqAKwAvICDgKvAesAbf9//WH8Xv3C/rwAHQKBAkIDmwItAmMCCgIRA6cE6wUQB3YHNgfdBjwGDwV5BFoEngPmAhkCoAAs/xj9jvoB+Y730PUv9W30ePId8WXvlOz96p3qv+lm6rXrGupL6d7oq+XP49Hlt+eP6fzsFOvl5/voH+c95/zsCe+k8VX3Gvgz+db7lvvy/QoDRAbwCFALeQqSCbcJAAnqCHoI4QioCE8HsQZxBW8FXwUxBS8FfQQXBIIDdATaBYgHHAo3DOsMoQvYCh8LuAu0DFIO4w5nDoUOcw1DDccNMQ1wDr4P3g4vDssMeApKCckIRAkDCiYK9wl6CUEIAwZxBOoDGwQMBUcF7ARMBP8CFAKJAXsBDgLOAh4ELQWeBeYFdAW+BIwEhQSGBDUFewXfBCEFcASlAjUBr//g/t79wPwP/CL7g/rr+Mv2w/VQ9E7zb/M88hbxy/BL74buTO607C/sUezj6zzsSOwR63PqvOpO6ljqYupe6YHpJ+qN6qPrKOyl7Pjtv+777lvwmPNf9+L62f0XAGkBPAMeBRwGCAcpB8AHpgj2CFwI3gcoB8YGOgePBswGAgYDBU0GkQYUBjEIZwpIChALuQsODNcNOw72DP4NLQ8HDoAOyw4WDe4MxA3SDZEN0w1mDbUMJw0yDAcLPAw+DEgLuAw5DPIJTQqpCcAIcQkJCOcGpQbSBBwE3QMqA6oD9AOiA74DVQMgA9UD9AO8A60DaQNxAugCyQO/AsMC1wLyATgBLv/x/OH87/ws/Dn8CPzY+jj5Ofck9S/0MPQj9Gj0RPQo8xHyX/C47kfucu7v7l/ulO2N7ZXs3eph6orqmeri6nbrgOzT7MPsVeyt68Xr2uy47ofwyfCF8AfyvfOR9lr6/vxUAHMDiANeAnwCxgKfA6AG1wnMCgwLmgmeBaAEbQTmAjgFcQgLCHEIewkaB/sGrgjJB4gJswtKC5ANZw7FDOMNfg4fD3AQhg8bD6gPHw/KDhMPlQ+xD7MO1Q47DwsOrw2hDb4MCQz2CgsKxwqXC9kKDgpaCf8HQQfLBkYGfgZvBkYGEwdYB+4G0AZgBtcFYAWeBGIEIgU1Bf4EGQUyBAUDdwGI//L9iPy/+zv7dfuI+yT65/iR97L1O/SF80bzPvNy8xbzyfEL8d3wf+937oju4O0s7aDsk+sy62Lrc+sq7Ersheuj68rryuuW61/rmOz37RvuH+4/7rnuGPDf783vVvNI9zP6ZP04//b/dwGvAgwDDwQuBYQFswYCCEAH2QV7BV4EBQP4AzoFhAXgBrsHfQYCB4sINwgJCrAMeg0JDkIOvA4ND/kP5BECEsoQ3Q4FDVwO4Q5pDuEQYxEOEJkPzw2XDCAMFwuxC1cNlQ4bDqMLQgq8CeUI5giOCbwKxQqbCc8IHgfIBcUF5wXkBqAH2QapBj8GRQSFA/EDRQQ9BF4DDwMPAnz/G/5K/dj7V/vg+nD5V/ii9tHz7PIr82/ySPO49AD1J/XD87/xavCZ743vRPA98qzy5/D7773u+Ozn7Mfssuxu7fDsK+wC62PqWewC7jju2O5Q727vP/CG8bPxZfEp8q3yePTe96H6LP0JAFcCLgMVAt0AMQKaBPcFZgVzBZQHYgf1BIcDiALFAjkDpgPaBbIGAQf5CCgKrAv8DK8MKw6YD+QOQw9JEVASthF0EWAQGA7xDJEMXQ3YDjQP9Q7bDR8MUAt7C3AM2Q1HDhQOrA0aDTYM/AriCpgK6gkZC6kL8QmdCLcHXgcACEAHxwU8BasEtARYBQUFSgQ4A7kBMwGVAIL+Pv1o/Sv9CP28/Iv7IfvW+iz5xfgh+Wj3pvbg9p31u/T28y/z1/IC8nHxdfAC76rudO5w7ivvve9b8Ivw3e/M73jwiPBA8I3vp+7h7TrtE+3T68/qN+1r8BLxYPGS8u3yhfLL8enxMvV5+mf+hwCQAloEkQMVAagARgJVAy8DtQNBBU0FcwP8AU4C4ALcAh8EngZoBzsHcAjPCZ4L1gwgDOsMmg4bD3MQmBEoES8RWRFYEKMP6g5yDcEM7AzTDJ8McAziDLIOsA+gD30P7A5aDroNVA0IDYkMEAw5C/cJDAmjCK8IPglxCY4IGAdIBgkGewW4BJwE8ASUBP0DhgMYAlQAjP8r/rT86fxX/DD6gPjo9tH1+vX19ff1jPa59un1TvUM9b30QPXa9af2dvcD9tbz5PGK7y7voe+w7y/wsu8b73juV+wg63TsVe6+723waPCe8I/wWvCT8RPz1/NH9c71kfSy87Py8/Gw8vjz9/bq+ur8QP77/xwBBwG0AH4C7QODAhMDTgbcBjoFAQWMBH4DowPEA4wDcgM2A6UFqgurDXkM7g7cEEsQxA/fDsUPxxFkERIRrRCKDjwOjQ8WECkQZw8vDpINZA3jDaEPwhBzD3EOmw55DVUMkAypDLALcwoYCrsJrwiGB6cHhQmhCXkIxwiOBy4FrQQNBHoDagMkAocBcgGiACUAi/8o/pb8ufue+m35jvng+d35Nvo4+mj5RfjA9tr0uPK68f7yTfRw9Ef0afIR8HPvMO6N7bfvH/Ge8B/xgPFz8PrvJvA18TvyP/Fx8DzwSu9m7pDta+5h8UTy6PCn8QbzifIZ8s/w4vD39HT3c/n0/jcCEwNNBKwC1f+i/78A0wGmBMwHOgfeBL4DhgLwApYFtAb9Bn8GPQQcBTwHjgdqDJ8SnBPCEogR/A78DO4LqAzzD7MRnxCWD8APkA80DyQQmxDKEEARsA9ODp4Pxg53DH0MFAwBDIgMXws4C40LRQqCCnkLZwtgCgYJ6wiFBwQGrwYaB6QGJgUWBPsE4QScAjoBAwBo/bL8X/yr+Qn43/Y49cj1pPaf9rL3Gvg79gL1//OE8hDzI/Sh9eD2VvVn88zw9u0r7lTusu1A7jXuqu0e7TfsV+zA7B/s/Ovl7E3t5O0g8B/xGPF08hbzT/Na9GDzpfCt7w3vUe+08oH2+voPAIoCLAMzA6YBsv9L/1QAIwHQAe4DuAWdBtEG+QOVAdMCmwSXBo0HNwgsDHsNSAv4DMEPpRBvEbASfBR2E14PWQ2bDvYQtRJJE+0T6xOfEcIO8gwtDMkNShAcEh0UABTREV0QEQ+nDYINFA2XC7IJaghTCUMJGwjVCGsJ+Ag7CEEGqAOAAiACcQKiBDIFlQPWAlwARfzG+c33Hfdz+Iv4NvfQ9vz1lvNt8bvw4fHi8uXy5vNi9LrzT/Pq8mPyBPDZ7fLuKe497CjvZPBT7QPsK+sq65nrrumu6p7twewy7cbvG+/l7vjwaPIV8+bx2/Bj8f/wsfGb9Wr5dfyM/0cBfQJIApIAof9xABoCcQPpBOMEFQScA84CqgJMA1YFMAhRCC4HmgiKCcUJ6AyfELoSxBPyEwYU5BJFEKEOPg/UEDIRyBAhEPgOcQ7IDnsPaRDnEd0SYxI6EpEREhAcD6gNFg0gDQ4M0QuZCz0LyQv1C2ALJApqCdsIvwcmBrgElwUVBnMEqgO8Ak8Acf4U/fv7gvtU+lj5Evkm+NH2Gfa99Uf1ZPWI9HzyxPAw71HvNfEx8qrysPOR8y7yT/Ee8efw8e/p7bXsHOw+6jTojech6BLoCudp5sLnwep97VPxYPW79rz1kfLP7zvvL/Bv9OP5gv1UAJoBAQE4ABQAIgHUAR8Awv5XALwAiP5Z/58DvwfqCXsJsQgkCBcHtQepCgENlA4dEY8SsBLWE9wTThLyEUoRJhCVDwIPjw9tEeISQhPrEy8UAxI8D4UO4A6cDzgR9BH7EYIRBw+wDMIL+gunDBYMCAylDO4LuArHCeMIVgc5Bl0GAgW7AmoC4wKAAsoBjAF9ASoB6f9l/an7H/om9071wPQd9Dn0fPRU9HH0c/TJ80XyvvD776TuJu1H7KfrtOuW7Ort8+4z8H/vT+2i7K3p/uZ65yTmq+UL5gjlKOd66Tvq5evw6+rsG/Dc8pX3B/tc/F8AJQK8AX4DkAOHA4QEPwI9AS0C/P8u/nj+GQDCAjUD0QOmBgsIxAgmCQYJyAtuDSwOGRNjFVAVsRarFJoTRBQcEnIRahE/ELcPPA+6D+4QVhLGE8cUGxX9EgYQjQ40Db4MZg6/Dw4QmQ8NDrwMVAtDCpsKegp3CW8I7AdXCJcIRQiPCFEJpQjDBmAFlgNEAYf/M/3K+lP5OffZ9YT2MPac9Yr28vXY9CX0pfK98v7x4u9572LuRe2u7CLsUu3a7FnrXOtH6RPmIOSQ40Llw+YG5/XnrOiV50bnQOm96VXq5usb6wTtQ/A28eX14fslAHgF6ginCaIKUwkvBf0CoQAU/cz8V/vO+FH7Tv4oAbAF+AcyCQAKDAnVCRMN1Q5CEPMTvxbkF1cYkhbBFNMTBhK/EHUQ1Q+sDgMOxA7UEBQTphPLEgcTMhPTELkO9Q3sDP4MQQ2MDe8O2A19CxYLNgtXCxYLOgt9C9wKZAqyCTMJVglxCLEGCQYDBQsCCQCP/mr8m/v/+hj6Mfl893b2L/ZU9ab0nvQn9OzyVfGG7/btreyW6rboVeh36A7p5+k06rLp6OiY6EToNOd25gXmQOQb40Di7eDC4RPjNuXt5wLp3+wx8sn2Ov2GAjwH4wwVEAsR0RBjDQIILAT9AAz9dvni9lj19fQX94D6yPyKAVkGYwgKDY4Pdg/vEqcUohbbGpcarxhWFtoSURDCDRIOiA4jDBsMZgvvCbQLmQwND7cS0BK0E+ET7BEnEY0P4A7GDjMNag3QDa4N7A1fDQkNeguNCY8JKgnACOUIxgiUCTIKzgkUCeQHQAbkA6MB7v+v/ev6IPl4+OX3SPfl9cT02fMC8UfuOOxK69jrQ+sk663rpuuK7NLsceyH7HvrnenZ5jrjW+AU3vvcjt2/3oHfOd9r33zgyuA14X/lEO7B918DjQ4VFbwZ8htEGmkYZhSUDSkIegCI93jxnev76GfqhO7X9Q78pQGFBuUIpws4Do4RkRUWGNMabxvkGSMYgBRYEqARLxAxEE8PkAw8CW0GggUvBeoGVQp+DaURURQHFdAV9BMXEtUSVBGbD4QOtAunCnsJ9gi6Cx4MAAx+DSYMXApGCtAJZwk+CvUK0AqcCsYIugVxA6EA8f3g/Cz7SfhU9qf0z/Kl8c7vTu4g7o7uZvCG8Y/yfPPO8UXxH+8s6pvnzuJV3nXeI9uc1/TXptUA1QfZZtoK3Fffyt0Q3MPdhOLQ7gQAjxKhIyAu4zL2MJ8qwSNYGI0N8gR791zsg+OB2Q7YXtzy47DwPvpbAVQHDAoQDqkSmReGHW8hkSMwI/gfsRtbF+QTlBGoDzQMAgh6A+H9UvsC/AT+ngNOCZ4MPBDJESARfBF9EjkU4hX0FTMV4RIeEHoPlA+9EIcSGRJCENsMEggIBW0DrwLUAx4F7QX7BuAGBQXyA3wEfQQcBTcGogQbAhr/KPp89vvzefHP8FXwvO+y7/ftm+sq69nrkuys7Kvqeeaa4QLdk9hD1U/T0NJa1Z/YK9sB3b/cQNy62k/Zdd1/58n51w/9IXozPj2APPg6JzQtJ+sZ8gi79uznBNqGziLK5Msr06zg3e39+O4DmwqhD/EVvhr4Hh4ivyKQIuAgRB5dHMYZJxctFA4QhguoBEP9QPe28Qzwq/LB96n+RgWCC6AQkRSCGDgb0h0jIFQf0xxEGVEUthDxDqkNkwzDClcItAUTA3QBrv8b/wMBYAI0BKsF8gSfBccGmQjKC60MLgzMCQ0FvQAH/Hj4afYo83Lx2u8d7XPtBO3a677tnO0H7ObqOuaF4M/cXdkc2DbZJtlD2drZh9jy2Eja0Nin2E/XatVp36jzdQqpJPo56UMrSMtFtzyDMZwgpQtP+WHnxNYNy8bBYL5ExqDTH+Pb9BkB2gj1EEYWbhwyI1glOyYhJWAhbh1WGBoVdxIuEJ4RFQ8DCrcFMfsp8+rwY+4e8i34F/xYA8MIQgyoETcVLxlGHv4geyGLHt8YDxTSEFwPAg9TDRQKfQacAlf/Lv70/SP+QQAgA3AFWAdiBygHfghWCdAKOwzqCiwJZAYAAi3/9/su+Oj19vLj8Q3yCO/l7G/r4ejC6BDon+XE4/Pg6t5+3YDbNNpi2ArYg9lR2p7bV9tj2FvVRNS822buaAcWIrE32UR5SVZFxz1pMykjJxL8AF7upN3hzTXBQryvwNLNuN1+7cP6IgJ/CcERhhiSIZUncCj0KGUk5hwOGBUSsg49EPEQGREQDxwI1v8G+HTy5fDz8ZX0KveP+ZT89P/YBC4LOBNKHMQixSXeJEYgvxqKFmQUjBLMDw0MEQY0AHD8CfnU+Ef7Wv0bAnAFDAX0BaQFzAXrCW0NFhALEjkQAwy9B40D8v95/eD6TvhH9vzxfOxN6PzkkOTz5QnmLOUL45DgYt5p3O3biNuI23Hd+90t3bHcUNmj1LHS6dTO37H1WhBMJ4I6+EY8RlhDzj96MUQjhRTr/QvsCNvIxl+827lwvtbN5t2A68r3ZQDsCEkSqRvLI0MnMygFJh0flRlJFAMP4w9GEmYTQhW9En8LswNh+yP1zfJC8lfygfKA8571Ivmx/ygHKQ/IGI8fACNZJBkiHR8wHekaIRj5E8cNpgbJAM/8BvqA+dT6DP39/xQBXgAkAFUAQAKFBoIKsQ38D2EPrg3JC38I2QVWA38AJ/4W+ZjxE+vk5S3joOJX4QXfSN3I293ahttg22jbGd3W3cLfP+Fu3gncPNid09bX/+I59fMOqCT8NdlCT0UlRGVAVzagKZAZYge99fjiqNG6xNi+YcIPzBrY5uPs7hX6WQSHDpUXXxw8HwIgeB3GGhAXNRK2D7gQ+ROfFq0XjxVXD7IJ9gNh/Sz6pvYx8s/w9e8g8a71PPocAS8KZxJHGtUekR8tIDAgvh8qH8EbXRVRDrcHcQJW/9H7svf79YH1iPb5+KX5Rfte/2oDuwiNDTMPBBCZEK0QVRELEd0NPwl0BCP/8flP9LrtuOfc4SfcrtcY0xLQR9Di0Z/VJdrs3KXfrOHu4cri1OGz3PzY89m54Qr34RDuIvIz8D/fQYtFjkU0Ol4tkx1lCJH25eUS09HEWb6pwCDK9tX14RLsZ/a5AWQK4BJnGY4a+hsgHAcZzxeCFeIR4BJIFvUYiBt4G/YWCRH+CvID8P3T+K3ycO2f6nXqJe1U8vf4wQBzCp4TxxlrHnohrSIiJCIkrSG8HX8XJhBECScERQAE/O34LfeR9qT3Fvj794L5rPyUAfYGqQriDLsNgQ0UDvIOag7zDDcKvgWQAPP5CfFP6Bzhztpl1uPSw88Nz93P5NBf0y7XkNmV2wjfoN5E297YHtTW163r7AH2F3QtdTjoPndGpkYeQrA7Yi3OHAYNxPkj5kTTDMXxwfXGtdAZ2tXgfuk88rr7sgYvDfARIhaaFrsW4RVOEmQPzA+fEwMZ2R2NH48d3xqJF6cSSg2kBnz/tfg28kjuIOxB69DtJvLz+NECHgufEREYTh0dIpMlryUrI5keWRn4E3wOkwnDAz3+3fpq+MT3mffE9j74NPu9/pICeAS3BRcHQgg7Cj8LPwvOCqAIYQamA6j+7fjf8n/spuZs4JbZY9Mnz3nNBM1JzjLRQ9Oa1dDX89fJ1njUcdSO2/TqLwDzE/Aili9dONQ9I0IaQms8bzO5J0IYEwdj9Yjib9TgzzbR0tX/2v/eUeTn6pHyc/qiAFIGvgoDDS4OLA0NC9AJhQquDqcU+xnOHS8gKiFGIJIekRtHFr8QRQr4Aff6efWA8FHugu/L8jj43f74BAgLtREAGGkcjh7sHgYdABrkFhUSqgxNCN8D6ACl/8f9cPzz++P7Gf0Z/58A7AAJAVMBNQHeAX4CTALSAq4DhgPOAS3/m/sl98TyMO1Y5nnf09hH0wLPzMymzCzNNM6dz7XQMdAjz97Qv9ZL47b1FQauE1Ih5CqZMU05eTzJOtY4ETLBJkgbCQy1+pjtT+XB4XbhReK44r7js+ce68XuAPXC+Ob86gEGAu8B/wGa//sAKQbbClARfRfuGnMe5iBuIU8hUiCiHikb0hUuEFQJ9wKx/iH7/vmt+1P9bf+FAjsFpwg4DLMO8hA+EiQSxBBBDm0LRQjzBXUEBQOLAmYByf+9/00AiQFuA68EdAWeBQYFsQP8AS8B8gDkAAoBi/9i/KH4EPS778HrvOf64+XfUtts1sLRK847zOHL/MsQzETMq8yH0HTZRuXd8/IBCA7OGdIi+ClJLzIxGjLxLz0qCSP0GLQO6AW//Uj4W/Uj843xUfEa8cLwn/KS9Nb1wfjN+UP4bPeO9evyr/Ld88n1j/omALcEVgoMELkVBBz+IAgl8yalJmQl9SDUG/UWQBFkDrEM/wp8C88L+Qz4D1USehTgFRUW6RS/EZgNsAdfAY/87/eD9CzztfIp89f09/bl+F/7BP5x/3UAMQGOAJb/qP7q/Fz7bfru+I73rPbi9ATzS/GA7uvrZukY5vXiOd9D2xLYmtR20WnPKc8M00zaNOLg6o7zC/zpBF8MwRLFF4cbvB7vHr4c0hiTEo8MMwgxBYIDQwPHA0wEjwWwBhgHMAgJCRkJ6AiSB6sEhADR+yD3tfOz8tfyGPQ093H61/0jAp4FRAlsDgMTNxbuF14XSRXXEioQpA2UDPkM7g2OD3gRKxMgFTEXqhjPGSsatRjPFR0R+woMBSf/IPq69s7z+/Fc8aLwj/BS8UfyO/SS9ij4B/mO+ZX5Lfnx+Lf3w/bu9oH2iPbe9ZP0YvTF8+nzm/RJ9FT0r/N/8Svvy+ww6tjoculn6hXsqO6a8C/zrvZC+RP8NP8rAQIDIAQ3A6QB1//C/bH8tPwz/U3+MABgApgE5QbCCHcKRQy+DaQOlw6XDeELgwnmBocEwQKWAQABJwGZASYCCAMFBAAFRgasB9EIvglECvIJCQlQCJ0HIwc5B4wHTAgtCQ4K8QrIC30M+QyRDZ0NJg1nDLgKwwi6BnkEygKSAXQAdv+0/i3+wP2A/Tz9T/2s/av9k/1Y/fz8v/xG/LH7RvsD+//6B/v1+vP6+Prv+uL6tvpA+pf58/gq+B/3+PW79LrzJfPU8tPy6fIn89jzcvQn9Sv2vvaQ97L4L/l7+aD5evlw+V35Xfl7+er5tPpk+0X8Ef3x/TP/LwBAARoChwIHAyMDDwM8A3kDygNVBOMEMQWEBeMFKAaRBuQG+QYNBw0H6gaQBj0GIAYFBgsGMAZKBnsGqga1BtcGBgdGB4oHnwfAB78Huge5B1QH8QadBisGyQUzBY0EJASnAwsDZgLQAVwB0gBoAAgAov9i//D+iv5S/hr+Dv7n/bf9qv1u/U39Xf1R/Uj9U/0y/bf8R/y7++j6SfrA+Sn5sPhU+Ob3u/fe9+H3LPi6+D356flp+sX6Q/vF+y/8W/xi/FX8Nvwf/P/79vsN/Dr8jPzq/DP9bf3F/R3+Xf6p/s/+4P4S/yr/Of99/93/agAJAaABQALhAp0DSwTjBHcF0AUNBicG/AW3BVsF6QSLBDsE8wPUA9ID2APzAx8ESwRfBF8ESwQiBAYE5QOiA2sDPwMLA9kCugKpAroC6gL1AvcC7QLEAp4CUQLoAYYBHAG5AFQA8v+m/2T/NP8Q//L+7f7u/uz+6v7S/qv+d/43/vr9r/1r/TP99PzG/J78cvxV/ED8PPxQ/Gj8hvy0/Nr8+vwe/UP9dv2o/db9Dv5O/pX+4/4r/2z/sv/w/yYAXgCLAKwAzwDrAPgA8gDUALUAlQBqAEEAHQD8/97/yv+1/6L/lv+J/4f/iP+T/7j/3/8BACcATwCKAMgA9gApAVkBfQGhAbUBtwGxAagBlAFuAUcBJAEAAdwAtgCPAHYAYABEAC4AHQASABEACgAAAAIACgAXACwAQQBSAGsAjQClAL4A4QD8AAsBFQEPAfsA3gC2AI8AagA6ABAA5/+9/5z/fv9p/1j/Rf87/y//HP8L//f+3P7F/rP+nP6O/oz+jP6T/qH+s/7N/un+Dv86/2D/hf+q/8z/8v8PACIANwBJAF0AcAB4AHwAfQB3AG0AXwBMADcAHgD9/9X/tP+W/3T/WP9E/zH/JP8i/yf/L/89/1b/dv+Z/7//5P8HACgASABhAH0AkwCmALUAsgCpAJwAhwBwAFYAOQAbAP//4P/A/6T/j/+G/4H/gf+J/5H/nP+t/8D/2P/x/wYAHAAwAEQAXABwAIIAkwCeAKwAswCtAKoAoQCRAIIAbgBVAEMAKwATAAYA9//v/+z/6f/w//f//v8GAAsACQAOABYAFwAWABAAEwAbAB8AJwApAC4APgBBAEAASABGADsAPQA8ADAALAAhAAwAAQDw/9z/2f/R/8f/xf+//8L/w/+5/7b/uv/D/83/0P/Q/8v/zf/Q/8v/0f/b/9//4f/c/9v/3P/i/+L/0f/J/8z/yf/F/8L/t/+z/7z/w//G/83/1v/l//L/+P8GABAAHQAxADUAOgA6ADIAKAAeAB4AFgAQAAwA+//3//j/9f/3//X/9f/1/+//7P/k/+P/5v/g/+L/6v/w//j///8IABUAIAAjACUAKAAlACAAHAAbABcADwALAAUA/P8AAA4AFQAYABkAHwAsACwALQA1ADIAMgA0ACwALwA0ADYANQArAC0ANQArACUAIgAYABsAFQD///z//P/6//X/8v/6//v/AwAPAAsAEwAZABQAHAAdABoAHgAXABAACgD9/+z/4P/c/9P/zP/C/7f/uf+1/67/t/+9/8L/zf/T/9j/5v/w//b/AAAOABoAJAArADEANwA0ADIALgAnAB4ADgAAAO//3//T/8f/vv+2/7L/sP+q/6f/qf+s/7D/tP+3/7//yv/V/+H/6v/2/wYAEQAbACYALQAyAC8AKgAkAB0AGAAMAP//+v/v/+X/4f/d/9v/2v/W/9n/2//Z/9//5f/o//H/9//7/wUADwAXACEAKgA0AEAASABRAFkAYwBpAGoAcABzAHMAcgBuAGwAawBoAGcAZwBpAG4AbwBtAG0AbwBwAG4AbgBpAGEAXABQAEcAPwA2ADEAKwAqACwAKAAhAB4AIgAnACcAHAATAA8A///y/+r/3//d/9b/yv/I/8b/xf/G/7z/r/+p/6j/n/+M/4P/dv9o/2T/Zf9n/2P/YP9m/2r/d/+L/5P/mf+i/7H/s/+n/7L/yP+z/7f/3v+4/63/qf+Y/7j/q/+n/57/of+x/6L/rf+t/6z/r/8wAI4AOQCY/wf/iv65/QP+qP5G/pL+Y/9SAL0B+gKAAk4ACQGYArcBNwASAEoB/gApAVz/tP+JAln/YP5o/yL+cwC7AP79cgDgAYsA5wI0BVIFbAaWBdECNwLj//r8NP04/bD82/yK/Xr/xgF7ArgCLQXTBegCOgHH/YP7Yv0b/M77FP77/3oBswBuAasBDwBu/0H+vv38/H/9Y/6R/QH+5frX+vcAFAGV/5sCGwHn/bYAQP4P/VcBnwBmAiEDuQEWBVYFogNZBFAC2P/B/ij8YPkW+Sv7cvy0/r4AuAFyBIwEWwIoANr+8v9CAMj/TwDEAQkCPQC+/bv7uvtJ+2L5fPne/aICrgU6BycIjwmbCDIEof6j+/j5//hH94D43v1DAGsDDwYIBqsG5gTFAcn/9vwk+0z6Efqo+8/7Tv1uAdEDCgVaBOoA/v0c/Ez5WPh2+vn9BwH2AowE8gNrBO0BfP1e/dn7Avv9+pb6i/s4/a7/NAIfBPsF3gZxBawEyQDM+7X6RPla+Sr7qfxE/6sB9QHDAfYBowCh/mP8HvrP+i38Bvz1/ZsAKAITBEEENQP+AvkADf5W/Pv6kPs5/eH+SAGLAuoD/gRxA5gCeAJaAfT/vf9KAMT/fwAcAsoCrQPCBO8DMwIcAXP+rPwe/Y78c/2j/3IA8wHUAmcCKQLEAekAvgCLAE0A0QCgAOQATACw//b/jf+C/2z/C/+5/tP+5/53/+7/IAB/AEgAYwCFAMoA3ADx/1r/Z/97/mH9r/1M/tL+lP9PAIgAhgHyATgAwf9r/1z+k/13/Az8HPzf/Pn9r/7D/mP/zf/3/tz+E/4E/mD/Cv+H/jH/JAA/APL/iwD/AKQBpwKuAnQBUwFEArkBmQH9AQUC+wEdAVAASwBHAA4AVQA/AD4AMwEEAcL/w//q/7z/7P/W/zsAYAAHAKv/Cf/c/kD/Mv9l/5wAogBwANMAeACSAAoBuQBIAJ0AowDs/6f/uP+2/3wAWQEDAY8A4QCJALT/nP+Q//7/igA2ALn/kv8g/3v+Wv6n/vH+D//Q/zsA8/8XAEEAPgAdANj/l//A//v/+P8rAEIA8ADnAcIBbAE1AaoAGAAKANn/gQDLASAChQJpAg0CawF0AOb/BQBFAJEAWAF/AUYCfQIKAs4B1QBTAE0AsAAaAE3/Vf9D/53/dP9h/xoAPwCJ/8n+Rf5E/sr+m/7R/vn/RQCl/4f/X/+O/tP+5f5h/iH/R/95/i/+H/7X/YT9g/0d/aX80/z8/N38+PwG/Z782PxX/Zb8hvyg/RH9d/zQ/LL8v/yj/X397PxU/k7+Hv0+/a794f5WAKoAygCNAXsB/QAJASkBKAIpAzoDyANvBMIEGgUcBS0FIQX5BIQF3gUNBlMGWAZaB68IOQntCSIKXAkjCYkI1gfXB3kH3gfKB+8GFgfCBnYGqQa5BQ8FZQUFBQUFAgU+A8UCxwLmANj/Tf+Y/jr+wP3L/WL9qPwc/Iv6Qflk+C33RvYz9R70kvM880DyQPEz8MTuBu5K7Ijqlely5z/mv+aB5yvpX+sf7ODspu+z8IDyqPUh91f6hf2P/24ATAGIAsUDjAXfB88KHwy/DPILawtgC6wKRgu3C5IMIQ7fDjMPmxBvEWcRxhItE/kS7BOXE8oSahO9EwUTGBMeE6sSEhOoEqkRDxEbEJgO6g39DeMNow7PDoANXg00DXULnAqcCfAINQijBpEFJASeAs4Ahv92/dT6YPgM9bPyye8N7QbrU+mj6PLmbebz5YHkRONN4T7fWt1u2xHZedcX19zXjtdU14LZzttM4M7l/+pz8YH3gfuR/Gn/QwItA7wFfwijCnAM9w4CDuIM5w1xDNgKeAnuBtsD3wLQAR4CBgbICA8MHRDxEDkS+BKxEdESLxQhFYAXRBpLG4McJB6QHmoeYh4vHYsaJBmcF1cXKRcdF2cXphaWFoEVrBSmE1YSzBFzEPAOrA16C34JMwenBD4DpQD8/eT6v/aP8yXwEu1e68foRebS5HfioOB438ndVtx12z/ZtNby1ODSSdEs0GzPFs/hzqvM1Mz+0HLWN+DS6vXzH/2DA8gFHwgJCaEJfQuyDJAPzRBnEd4QGA45C/EIYwV6Ae3+2vrJ94f2QPd++Tb+BATvCEQNDBAFERcRXxLqEjkWuBvmH1QkWCcUKEInByZSJLciFSGcHjQbERkYGLQW0hZ2FrMWrhYFFcoTUhJ8EcoQbxC6EOIQ6Q9wDikM9AjLBroDrf+X/FT4P/OV78vr7+lY6fbmK+XC4+Xghd783KzaktkH2XHX9tTE02nSLs90zrDNUMwMzKvK4MnEz9PZEePb70X7WALLCPULjgzzDbgPvw+BESgTpxL6EdQNNQoCB5sD7AAu/Fn3x/LU7jPuZ/EA9sH97wWlCzERphNlE84UUBcmGmQfASVjKOQqxiwlLOcqKiv/KAwl1SKaHusZhRe/E+QQ1RCfEEMRYxJWEq0TrBSrFF0WWhcZF5UXkBaiFL4Stg5cCikF7v9y+4P2ifKa7grrnego5v/iseD/3oHdwNwK3P/aq9j11iPVStN+0v7RDdFHzzfOHssWx4TD0sLRxrTQGuCu7fP6QAbJC30O6RCiEjMTThTsFEgTgRGLD74KmQZrBRYDoABi/zr5yvNg8Hfsqu4T9Mn6AASHC2AQuhQOFtkWGRooHb0glSTcJsonByniKY0qiCxDLWoryifdIsocPxfuE/MQrw9qEYASExNhFAgVEBZTFzsYHxkZGVAYqxb8E7UQLQ2cCCAEBADc+nv2TvIC7cboauW/4hfiEuEP4ETfnd0x3JPaw9ja1jbVM9Oy0THQ680EzGLKDsgVxYDD4MD2wGHJ3NQf4uTz+AFdCrwSFxbyFsUZkBncF8cWGRMADxcLegZ3BKsDbgP8AyQBefxc+ObxWO/b8af1Vv1MBaML7hBrFMUWMRqeHXcgViM2JGokjCSZJJ0lLyhlKjws7ix2KognWiMpHvsa6hcxFXoUFhOQEaARXhKFEw4VPRZUFr4UUxK6Dq8J+gb3A6X/Tv0j+Qf0g/B37Irptecr5tnlzeS84+Hi/OCS4LLf+d2X3sfc/Nkp2RjW9dPl0vLP3M1vy8THc8X9wsfCzMiq0tzft+55+m4DZAu7ED8V2Bo2HgAfJh5AGQcSxAuiBt8DxANdBP4EjATtAS7+o/nl9gT3nPgW/Ez/TQEPAwoEWwZQC8YRBBogIRQlpSYBJa8i9SEEIlwjXiW3JZUjLCCXHMsZ1BhPGdkZpxlbGJIVxBL2EFsQ2RCeEbQRgg+8DKUJCwZ1BJwDvwJ2AuMAD/5O+zP4kfWJ88rxSfBG7hvtYeyv6/TrB+zW66rrwupL6Wznm+R64Zbew9vI2TzYudbR1cfUdNOB0v/R89Iq17feMugb8mr6BwDTAzQGPgiJCvQLLAyRChoHDgO0/z7+3f6+AJMDPQbAB90IiAmxCZUKJAw6DeoNdw26Cy8K9wiXCKAJBQuwDDgO5Q4ND7kO4w7JD9IQHxIqE5ATMBM0EuQQaw89DqoNww2mDU0NZg1+DfgNIA8JEGkQMhDjDtQMnwqpCIEHuQYIBoMFswTxA4IDBgO+AmwC5gGmAQ4BagDY/wv/jP4b/hj+YP6+/hf/uf7r/ef8vfu9+gr6Sflk+O32gvQ48oDwIO9O7pDtmOyE6+/pnOjX52HnV+h06QjqCOsm69Tq4eqZ6pnq8uoz6yfrkeoP6vnphupg7NfuD/Fp83H1Efcp+cr7DP+LApYF3wd9CeEKIwyODQAPORAeEVcRKRHkEJ8QiBBpEP4PSA9EDmYNywyDDOAMjA0nDqcOGg+iD10QChGYEUoSHRPCExEU6hNbE7IS+RExEXIQyw8MD1EO0g1aDf8Mwwx4DNkLzQrCCZQISgc5Bh4FKQRoA5oC5wE7AYUArv+A/tP8xPrJ+N/28/Qd8yrxI+9B7XTr5Om16M/nIOcn5vfk2ePS4j/iROKd4jPj/eN+5NDkGuV55Srm2ebT5+7orOld6rfqF+tx7Gfu6vDd84L2/vhz+939fwBOA0QGDwk7C+8MFw68DroPlBC5EMEQTRCjDyQPqw7HDj8Prw8nEEUQ8Q/MD+MPDRB0EPUQcxEGEpYS4xI7E6ATyhMWFC0U/RMdFAMU2hPZE18T8RJvEpYR/xBaEFwPXQ5VDR8MGgs2CjQJOAjtBj8FnQPFAfT/tP6I/XH8kful+u/5Uvm8+En4rffb9qP16vPa8ZPvc+2H6+jpw+ji50nn1uYI5rHk8eIz4S3gE+CU4HDhCOJL4uXi9eOe5ZvnPek16jLqo+k56X7pAOtj7TfwGvNv9cz3mvqZ/QEBXgRNB8sJjQv+DFoOnA8DEWYSehMLFDYU/hNoE/gS0hLKEgUTJROrEh8SqBGDEQsSXhJnEnISDRLJEeER+BGcEooTGhSTFLUUQxQTFDgUQxSNFOsUqRTFEyUS4g8oDnENXA25DbwNnQz7CkkJsge5BvUF4gRWAyYBjv4n/H/6avmo+Lb36vV986bwre2y6tTnF+Uz4mTfcNzH2RLYwtbF1fvU19Oo03DVA9ll3srjFuhV64DtCvB/8xr3DPpJ+0H6MfiL9mT2c/il+yn+Tv+Z/2b/MACCAj8FBwgmCt4Kjgr9CRIJ3wgNCt8L0g0dDz8PRg6JDckNBw9qEaYT4RQfFVUUohPJE68U8hXoFhkXaxYAFkEWIhfeGEAaHRsKG84ZzBgBGH0XDhfRFZMTbxAoDVoKXwi4B74HBggsCIYHoAZSBb4DTwJhAOH9Ifvu9/X0GPO18VbxZvGf8J3vOu2i6enlueHL3Xzajdfy1NfSTNE30LfP9s6qzdLMDs7m05jd0+i88sT4VPy6/gQCRAejC50NlQtEBQ/+WPmc+Xn97QFGBPcCBQC6/Rr9p/6iAcID8gS9BC0CQABpAJMClQelDTASvRTmFFUThRK7EwkX8xqzHD0baxcaFOYTSxZuGrIdwx1xHC8agRgaGTsachvxGukXKBSLEPYO9g+YEV8SwxHJDvsK6wcWBWMEawTdA6sD2QH4/97+I/6L/if+5vwQ+uP1VfKV75vuce7G7YfsBepx57TlnONR4ardfNhc1MvQ2869zgHOxczlyi3I4cZny7rWcub19+AE2AoxDt8OuBGmFhcX7xVIDgEC4Phb8jj08fo9AK4DHwGO/MX4EPaX9s333/nt+5775vqC++P+/QYxEdwa9CGcI3YhJR1OGeoYFxutHacdwBmqFP0RehNAGTog/iM7I+8dVRZeEFUNZg2KD/EQ/BBiEFMPbxDdEjUVZxdGFX8Q7gl4At7+i/1i/3UC9AJ0AiwATP4O/i/+Y/7G/Dj52vTj8KjtH+zr64Xrnuun6vnn9uTs35PZENXx0cvPMtBBz8/LBMohx4HDhcJKxBvM09/E+OUMOB4mI6YekiANH7UeYCEAFtgGzfcP6frqRfezA5cNQgrl/X3x7uY55JTmn+o68ZX1l/no/88ILRZXJNsvyjP+L6MnlBshFO4R8hOkG34fUx6FGssUmxMiFvoXLxb6DmEF2f0x/KAAkQinEYEXMRpTGiIZ6hk6GjgaChh4EpMM1AYnBCwFQQiOC3AMhQnjA5L+xfqj+VD5o/eR9SzyD/A58Rr0fPmi/an9dfql8srpkeOo3sTb0Nnr1AvPxcqYxzPI3czazgfM8cZbu8C1t8Li2Hf7mx2gKmktaCa/GpQc9x8BIA0cMArU9UHp0eg79XUGBxC2CzD9xOpO3lfa892M56HwHPk5AYIHChK0Hj8phzIUM5grDyIqFukPOBJyGOUhASZrIiga4Q85Ch4IPggBB5ICuP0d+kn8hQPsDEsWrhq9GtwYcBV7FDUVzxURF/wVuxIxD2gLNQnxCLIIGwevAzf+f/iu9SH1yvaR+aP55/jT+LD4oftR/5v/Of51+Sjy4uv45UzhUd6G22rY59Tm0cbPgs/g0CXQiM8+zfjF+78tv6PIJ+VICnglUjXBM1klpB3+GmAYnhihEsgCFvaP8FPzEAH1DBwNtwJr8tvj/Njq1svbmeMF9EMD3QwfGF0eRCIuKBsoRyUmIWMZWhEiDdAOzhbsIRsoMiZKHuETggqwA/f97PmB9/r2afmV/UoFCQ8ZGCQfsCBIHa4WPg/3CuUJSQzwD00RCRJQEKwNpAxyCmYIIwRR/ef2z/GG8SX0Dfih/Nv+wgC/AUYB6wErAX3+Y/oz83TrMeW04Djfd98N37Xcytho1N3RX9FF0HDPac4WyoHFYsJLxBfYifl4GXYxizbAKQ0dmxS0EGUT3hOPDCgB/PZN8vP4GgX9CfYFR/mK6THfE9pI213jQfCoALUN8xXQGvQbDB4DH7Qegh4hGwgXxxIfEdgW0R+dJt8mLx50EoEHtv95/N35m/qd/Lv9MwJSBl4LqxIsFhgXIBW3D9QL9AnPC6kQAxWJF88VihHNDFcIIQYVBC4Brf1s+VH4mvpc/sABQgHx/dT6JPn9+cD87P8QAq8BTP6r9/Pwlusa53vkkOHY3FDXn9K30KXTHdni27rZiNP5ywvFNMKGxpPVh/FNEWQovTHsLGUfcBRQDwgNEA4ODbsF2P2e+SP85AS3CpYGMfqm6sHdR9gV2VXfzO2G/pUM0ReqGl4ajhrCFwMW5hXhFIwVnhagFrYawiD5JM0jXxt1DxAEnP06+w37yf05AdMD/gY3CggNlxABEzkRGA6hC84ISQp3DiMSKBeDGJkVoxBzCV8ESQH5/wYB1QDrAHsBtQAxAdsB+wD4/yH+jvtY+o76ufue/nMCrAO+AQz9X/Tb67nk9t1F2xnb4trM2/zb/tqc2/Taz9f51I7RhsyqxzTHA9Af6mcNHidpM40tEhtSDw4Kxwg9DlMPhQk4Amv7JfzKA1kJcgap+Y3pQd0/1ynZWOIr8TkD8RE2GYoZ+hW1EsEPig7sD2MRKBTyFksY6xzWIiAl3iEZF3wJNP/3+h/8IwA8BRUKSw24DsQOogzBCtoJoQjJCGsJxQl9DKMQ1xRJGJAX3xLWC3sEfP8a/iUAPAMeBiUHPAbkBRUFZAN2AZ/9L/p1+RP6Fv0nAX8DGgUbBXwBWvsN9Jrsz+ZV49jgXt+830DgY+CO4EvfPd3e2RnUatArznnLWssEzd3WYfHVD0sl7i6QJlQU9An7BlwGxgzmEcwLgAXPAqj9egKnB/b8svGk5dvYANmf3xvo+/gBCRkSLhXhEpIOrQszDNIMpQ43FP4Ylxt9H9QhmSPrI7ccYRCfBGH82PkR/v4DoQmoD3YRmxAxDyAKlgXTAwgCIQSXCF8LkRDKFZoY3xpjGE4RRgp9Ap/9RP6kAGgEwQfEB20G6wUUBBICcgC6/Bz6MfpH+3z/OAV4B9kHZwYkAdL79fVN7svoP+Xk4VDghOCL35jfzt7C2ojYJtXj0SPRTc9Kz8/OhM5/1QrmFgFPHMAqNitMHhcOFQYFBNkGlwtVDHEIkAQpA7cBAwDr+lnwW+Z14T3eb9955/7xbAGqEBMXbRcaE3UMFgrpCuIN1xOwGLAcUiDEISkh8BwtFTMMKwQ8/9z9XP9WBO8KlRDAE8ASeQ5NCVgF/ALHBOAJpA5RE64V/hU7Fy8X0xNADiMHOwES/93//gLKBqUJ8QqPCcoGKQRlAd3/AQCiACcCggP7A9IE2QXxBXYElgH+/If3gPIx7eToYuYY5NbifuJz4Ibdndno1KTT+dNI1NXWJNm12ejYtNPC0U3fWve8EBYjOiRAGasOIAZwAg0H8gu2DGIL1QWRACAAyf5k+ejx4+mQ5IfjD+Wg6uvztQAeDLUQaRHIDkYLFgtfDRwRsBYdGwUcvhvOHIEdxhuwF0APXQb/AtcBhgPICLgMNRBmEqUQVg10CbYFagTMBa0KvBDGFN0WXBY7FaQUWRKYDj0KhwWRAiEC5wPOB7MLzQzjCgAH7wLTAE8ATABiAXQCAAJ8AsYC1gLQBHwDtf7U+iL2dvJE8Szuz+mv5u7ia95E3KbaB9lg2Y7ZpNiJ19XW6dV41/fY+9SO0KDSq+BB+xQVfCHAIaoWaAhhAW4AIgQOC4ANaAnYBlgFFwSBAQX6l++u55zkWeSK5k3sAffIAgcOeBNEEUANugiaBkEJ7A7sFJsanB0QH4UgGiCLHCQVLQ03BtUC0gOeBsMM4hM5GM4YuBSjDXEHBgQaA0IGfAzLEsQXKBmuF7kVcBMKEFgLegZXA1cD9QRBB5gKmQwtDfALpgdXAy8Asf6a/ywCHgVCBisFtwJ9AFf/9P4m/T35j/Xl8RHvsuw16XnleOJB4BzeRtxx2DrVHdR71cDZI9zX2yra0NdX0pnP6NG23MX0VQtwF1cbchThBwYCnP5e/8IHogxCDBYLlQjABcEDsvwh8uPpuuWG5WXpfvDR+ZkF+g0eEaoPFAuiBpEEnwZODHwUUhwLIQwiACPcICcbWBQECisD/wIhBiQMjxPFGAcbxhn0E9wLZAV3AjIC8wbzDuEVChx9HeYZvhYkEt4MBAqWBuAEDQcXCUwLWg5HDhML0QcNA0f/8v+cALEBegThBWIGCQahAtz+9PtT+A72h/RD9Kn1evUz8j3siuTj3ejZs9gS2vza/NlX10rVNNVm13fZ89jh1+HUuc+LzgjXY+jN/5IT5RjqFOcMKgJt/iMBJQSsCrsOGwxuCvAIYAT0/hD3Ru6B6RvqtOzy7433jADgB7kOvw+oC6QJwQduByoNrxRzG14iIyTRIewfthsZFiARfwxdClsMVBB4FMcX8hjlFcYPXgpNBnIFFglmDcYRNxfzGJAX6BXkEb0OVQ1uCrQI6AhMCfMJLgqkCQsJYAjEBdIBFf8Y/m3/9AGjA80E4wTeAnD/mPu4+Ar4dfdd9jH21PW29Y70EvCO6QXjid0h2kLaQNzh3cTdsdoW113WZ9fA18HXPdZY02HRENEm1srlKvipBHsNHw4SCH8DoP7Y+88ASAewCvQNPg5UCgwEt/z79UzxrvFu81n08fhs/tUDsQonDQUM/grUCDUJewzTEIcXgxwMH7gg3x6tG00YTxSkEi4SiRKnFJYWoxh6GTIY3hXOETMNuwrhCuwLXA+DE7gVhxcAFx4UjhHODicMFgv3CgwMzA39DTUNvAtdCYgHgwSQAML+Jf/NAPABEQK8APb9K/tn+Ov1t/QM9bT0efPN8jDySPE+8ObtpOlG5bXgzttX2e7aX95m4Kbf2tvD17nVitRJ1RfWItU31HrTNNjQ5W7zp/zMBJsGKwP1ARcAg//0BHYJ6wmxDMkMvAccAzj9aPhF91f48vmZ+mH81/+RAgUHZAp7CpUMFQ5vD2cTfRWWF5sa7xrMHE0e0BwoHM0ZoBalFgwXkhY/GP4ZbRnLGD4WNhI7EcQQZQ9KEEcSrxTuFi8XgRXfEYkPmA/HDgsPvQ/YDQwOOg6CC1AKmAi3BQIDFwBa/x4AKQCk/yr+8Pu9+Q33D/Vq9PvzWPTQ84rxTu/p6xzpxeeg5oDlqOMA4jLeTNrA2Qfahtsc3avbOdgF1azSMdJU1LLWntjk3LLkZOyz8JD0l/j6+4f/SAEfAhAE2ARVBKQF3wZGB9QFswA+/ID6s/oZ/ckAsgKIA5kE7ANqA4QG3QuwEDQVMhiWGD8Y3ReiFqsXOBtjHOAcRRzCGTQZUxj0FuMXghj1GEQaMxnEFhMVqBPnEh0TLRTFFRMYDhpXGZoWVBRyEuQQHRD6Dw0Qzw/+DcsKcAipBrMF+wTMAwgDHQHI/s78xvo0+Tv4gfdd9b7zuPKZ8UDxtO/j7ZfsUOoy5xblT+ON4dvgIOA43y7dLNqR19/VeNZ62NXYRdiA2EXXFtVf1urY0tyf5efrmu7S9Gj4afex+jz8WPvT/x8CZgLFBv4GsgQ5BLYAgv9h/37+GwBCAWYDXAevCTUMUw1RDcEQxRLrFLQXbBjOGWkcRx1yHSIgqB8cHaEcqxoHGUQaqBoCG58bshrlGbMZNhodGpQZ6RhhF9YWqBenF18YbBgcF+sWiRTHEbgPcA3KDN8LxQrGCaoHwQVoAxgAb/74/aD8qvp1+Jz1MPO78f3wJvH28QTyhe9M7H3pf+am5eblauVU5TPkveEG3zDcDNoC2VzY7td+1yXWvtRn1b7WftdN2NXYatzE4bXlvegO7V/yovU8+DP71fzR/U4BfwG2AYEDiQDb/tr+lP5PAc4EQgNlAloDMwO2BdwH7Ql+D6wT2RQzF7IYOBnZGj4c8R04H3IenxyHG28c8B18HgEfBB6nG6UbJRvKGlUcoxspGzgb6Rk8GskbqxsQG48aeRmIGOAWQRTFEmoRMw/DDYILcAh6BnQEkwIuAuoAOP+s/c/6Zfhf9/j1/PM+80Dxbu+u7xnuUezF6xjqT+n+6TrotOU+5D/ipOCI35fe892U3IPaMtjX1jnXFdfV1sfWbdV91KnTpdTj2vrhT+f/7GbwQPDY8bP0g/WB+ZX+yv9KA5UGNgRHAjsCWQBh/xYCZAM2A30G4QguCnIOfw8WDtcQcxL5E1IYnxkcHP8e0x7wIDUhJx/4HfsbDRwVHUUdDB2sHL8dTB43HV4cHxyEGkUZjhnAGCAZsxrnGQ4Z/BjWFmkVvRQNEkUQ7A7aDCsLtAkfCYQI+gYdBUgDIwFR/rn7n/qO+cT3rPbT9AjyqO/S7U7t0+x06zTpKOYo5Z/kAOOy4r3iyeGf4CjfCtzv2b7at9s43fXd9tsK2vnYf9hz1/jV9tb+2ubhC+jx6vvtBPHX8if0GfVC90z5PPy8ACsDagQLBIgBvP+LAKMBWAKkBXkI9ggmC70MjQz0DrgREhN6FcwVzhQmGGIachxCIEgg5SAiIHIb8xnjGtsa6Bw+IAIgYh74HMkayhrSG2kbMRsZG0waxxhOGFEZJRh6FqMWERUKE2MSfA++DXkOqgxfCpMIEAc4BWYCngDd/iT9uvvD+Qr4dvYg9Dry7fB+7mjs9Opo6UnpYeg/54fncOZ95M3h3t+z3sfc59wh3oPfQ+B33qLb2NmM2TTZYtnR2aHYr9i427rgmuWi6I7rWu6O8NDxfPJl9UP4fPms/HD/fgCnARYAnP4lAFwBKwK0BFUHMAj0CQIMXgxFDiYR3BHfExUY6hmDGpIb2xrlGiwdxx39HQseVxycHOMcbhvmGxMdMB5qH38ethxaHAUcpBqnGcwZyBkxGtgb7hvDGWMXYxU/FIYTrBF7D10OjAxYCTUHoQVZBB0E7ALPAV0ABv1o+qz4RvY19J7zFvIf8FrvGe6d7fTsx+p06NflBuNB4cTgI+CZ3w3geeC63mTc1to02f3ZdNsj2wncmtwC22bZlter1z/c5+IF6Ivq6uvc7QXwOPLM9Ib2pfg/+wb8zPxG/mP+CP+2AFYC3QLvAqMDWgTRB7cLtw2DELoQrw8HEzkWyhg3G70aWRsNHRIdeRw4HqgfTx7lHZodvhzEHOcckR0OHz0fHR6oHpwfwh5pHesbghosGp4a2RkVGZ8Ylha/FXgUQREND+AM1AorCsAJegjJBnwFeQPm/7r8JfuY+Xf3C/V88pjwU+7964rrDuxk7P3rnuqS6Evm4+Qn5Bbj4uGG4Nff6t6q3CvbFtr22cXaCdsZ29rZ19k32nHX5tWi10ndXuVV6pPsY++m8Uvx5vHU9Lj23Pdo+xT+xP7V//39Vf0Z/yL/mgHHBEkDugIDBpoJFg2dDnoObhGXFTkXixj+GaEaThtbHXofrB+5HnscoRv7HXUfQB7gHXceER23HegeXB5nH8IdrBt9HGobiRoVHLIctRvEGe0XRxc1FpwT8hFjESMPzwxhCjoHJgYOBlQE4wLqAWf/e/13+7H42/cH9+HzYfGm7y3tyOxa7NPpB+gx5mfkp+Qt5OHhU+F34dbf6t0/3ITb39v72+PbWdtT22bbsNpN2tbYndf42PzbIeGO5m/qWe4+8bPxufHg89T1LPcA+sz6Qfy9ACMCKwECAoECNQE0AfQBdgKHBN8GAwnUDPMPsBC+E9UWlheaGX4ZAhqkHPEcLSDAI4UjyiJ/IE4foh+lHp0d4BxiHQgecR1GHTMeex43HWscHhtAGfAYIhiBF2QY6RerF1wXERQ5EQQPbwx/Cn8Iugd6B28FvAISAX0AQwBZ/iz8kfrJ91n1IfLd7o7tPuxA63DqC+mQ5wvldOO049LiLeGw4N7fc94u32jfHd2I25TazNpw3GXc2tve2kPZOth91mHYEN7a4iToDe2K7wDxqvKl9Ev3lfo9+hr5efxb/hj/jgCLADMB1gKPA6UCwgJvBC4FWAb0CAwLDw7SEhgWvhj4GUsXfBeIGQgbhB94IQEiiiLUH5ceMR8fHsUd7x4wHsQcFBxUGxccRx1aHfQcvBtRGqwYRBemF5kWEhVAFoMWVxVOFOwRmQ/RDlUNHQvVCPcGJAV5AoEAWP/0/bP7tfml94j0DPG67SPs6+q76UDp8ecd6OrnueXn5Urlp+JF4Pnd7dzh2wna7dfO1/3Yj9kU2tzY/tez19PV6NSf1RnZTN/Y5KHp++1q8dPzE/aI+JT5x/rf+p35KPue/G/+4wIfBCYDbwNkAtwAPgEQA50F5gmRDDUNzxBWFXsYmRruG0UdHx2fHMcdjh5iHyYgHSDUIGMgQR9dHt8bxhqXG5kbdxzEHJAakxoPHC0bkBpYGlcZBhkjGcwYPhjNFogUpxPUErkQFA+gDccLaQjsBCYDHwElAH3/nv5c/pX7n/jg9obzJfCR7vnst+uL66XqSuq16dPng+Yo5ZHit99o3mjde9t82UHXctST01LVmdbJ1i7WbtWD1IrT2NOX1rXcRePe5/PsEPLN9Cz3vPpg/TX+7/4j/lX96/5i/jn+GgH7AQwCrgHBACcBlgHMA6MH5wv3DjoP4RHdFkYZ8RsDHgwetR+4H5EerB+KHxUe/R7lH00erBznGr4ZMxpfGpMa5xr0Gb4Yihm0G0IdZx0QHGIaTRnPGFQXohU5FZAT/RGgEL4Ovw6LDQoLAAoICd4GnwPnABf/D/1F+jv4+fby87HwUO6A7Czsq+sd6wrrUeoN6fPnlOef5ifltePG4effjNzq1zfUfdKS03fUJtSj003S+9HE0DbPVtNn2oLhWOlW7+Dzjvgi/GL/rAPhBIcC/wD9/638C/z7/XL9LP99/t773vwE/N78DAIuBVgHjgknClYNgRLfFlUb8B3hHWQdIx19HcYdzB2zHQYdZRyOGnQYAhn6Ggcbghr9GloZmRfgFhgWoxhUGgcZbRnCGGIXgxjmGHYYsRcJFb4SPBE1D38Orw4HDR0Ljgn+Bs8E5gKSAGP/3/5s/aX7Cfks9pf09PJn8OHtFuw96sfoXOju55/nJueN5f3jT+Mu4dDdkdp+1crRCNIO0xLUN9Ts0zvUEtXW1YfWXNu14h3pDfHA96b7BABcBJUHkQjzB0IFhQFf/0P9HPxN+1z6ufmc+cv5Xvnr+1v+t/8oA2UF5gcDC74NlhJgF0IapRxoHnwf+yDNId4gCx8wHXocURtMGeIY4hfBFhMX/hZRFsgUYRR/FDIUUBVVFpcXBhiCF78YjhkBGigaOxjfFX8TUxFkD24NqwscCcMGjQVTBPUCNgIgAVb/hP4X/rr9N/xf+Sz3HvT98GLu8ux37d/sFezr6s3oAujQ5kzlE+Q34VDb7dQk0lDRo9Mm14zWLtb21cXU/dWj1nHWF9nQ37Xnle//+MH+NgNuClkO/hB8EQ8MeAYkAbX8ffrV9yr2svU99dT1NPg0+579aP9LAagD2wU5CIcKIw7bEwkYzBtdHkIfCyJoIjwhBiCDHI8ZARa3E20TABJvESIRJBFvEtYTnhQTFJkTqhNoE4sTKBS9FDoWXRdiF00YgxheFyQWKxS+EgkRug2rCrcHYgWKBMID/gIhAuAAW/9X/e37YvoA+Xz36PTx86DylfHc8lzyQvHX71Xsvemu50fk799t3CjaadnC2TrXSNU11RrV4Nds2AfXUNYw0srPFNOH2v7kK+9M+BQBAAkNEF4XmRx7GwEXExGHCAECF/3A9e/wJe9e7eDuYfGI86v3KPvm/aQBoQQrBUUG4AlzDi4U1Bd+Geccjx+XIlwl3ySrIvQd2RiPFIgQsg0JCvoHOgg/CEQKaA1BDzgSxxX9Fa0VrhUpFLoUyBXtFRIXkBfzFrUW/hbnFXMVyhOPDj8LYAdHBGEDm//T/Vb8S/o3+277N/zl/Gn8LvzO+kX5ovhN+GH30/Vm8yLwSe2e6ufnjOXy4urgZN6G2RrVPtKL0oTV+tbS1a/S0dDuz0/RZ9TX1yziPeyz9IsCaAv0EQEcNSGpIvwgaho4ETgIeQDR94PxbuxD56PmyufF6rXwyPUK+un9XwExBJEGoQpADjMRwBR6FSoXABvIHGUgkCMWIkIgbx0fGN4TVxA+DIEICgVsAkcCYARjB4YLMg+9EfAT1xScFocYlBjmGF0XyxXKFUUU/RTrFT4VuhSNEVcO5QtlCc8GxQM+AUL99vq++vD5qvry+kD7LPxQ/OT82fz5/Ef9Qvzp+R32HvJF7j/rVehj5KfgbdxK2SDZj9hL14TWwdTS0w7UftMW0yfS+M4+z1XZEOeL9PYCCgzQEcMaJSMrKa8qtiQCGqcMzgKU+pzx9Oti5LXgX+HX4b3nMe5H81j6HwCUA7UGnAcNCdkNKRHEEqwTBhQPFk0aZB/sIfQiziElHQMa+BayEiAOMwhNAlX+5P2R/rcARAXnCOYMwhB8EiMVjhhYGUYZAxndFrIVYxVVFKsUBxV/E80RcQ+DDFYL7glVBvgCLP/W+lb5Sfnk+Tr7pftt/Jb9Q/6+/2wBOQGAAKX/V/wX+Nfz9+6v6rvnSeMY3XzY7NLF0BbTL9SB1s3UAtIT073SM9Vd1uDSWtZJ45vxFv5VCi4SBBfpIcAsPDCWLSElwRntDpsGjP3V8h7osN4W21rbw9475i/sp/CM9iX9tAPPCOIKcwxNDlgN0w0iD3wQKBbIGoIdox7iHg0gah+4Higb1hQ8Dr8GywJ/AAj+Vf1W/bb+wgKICP0MDhGFFXEYshqnG4MbHhvgGWkYhBbWEyoRNg8gDbwKngjGBZ8DWwJcALP+yvys+xP8/Pw3/n3+m/8iAewBjgNmBO0D7QJeAY3+Hfpy9aLw2OuT597iwt2O2LvT0dDQz0nRZ9MY04PR09Cy0SPTbdVk04rSat9Q7g75RAf+EdcVNCCOLgYz4jDPKi8fUROWCzwDUfb26fbfLNoJ2qzcweLK6ADsYfFg+YkAEAePCiIM8w5jDlAOmA8yEN4VGhtcHZoe2R42IY8iRSK6H1EZHxLDCv8EZgFj/Tv64/jh94/6pwDtBfYLxxEVFhkashwUHnYetB0IHAMZhhXuEeoOWw1pC9MILAbVA4gCJAEGAB7+rvv6+on6CPve+1D8+f1X/58AZgKMAzMEgQQXAwb/Kfqn9T7xw+yu5yjh49mX1DHR9c6TzyTRwM+mzrDP78860rTV3dLcz8Xa++oL90gGCRHoE/AdVS3uNQQ4TTOgJ+ccXhSUCyYBvfLq5KXcINjs1+XbquBX5CDoOPDN+FYAfgYZCZ0M2Q6oDlcO7A42EhcXNhthHOwckx/2IkcltCTCIAMbGxRPDf8HWwJ1/LD3IfSY8z/2PPrc/zkG6gsoEvYXpxuDH80hkCBDHzAclxdOFLMQ8AxGCYgFPQKWAG8ARv/x/QP9y/tq/Gr9dv0H/p/9lf0S/xoAUQHzAQACFAFr/pX8/Pg99fDypu3l57vh5NqU1rvTudHF0Y7Qts24zVbOKM+T0kXTCc9A1crlMfHd/+YMQBCIGbwnfDOrOcY2Cy98JakczxV8DID+w+9K5A/d/dlt2mTdUt/m4OLm7e6B9mL9UQISBi0KAwwRCx4M+Q4AE+kXaxrYGcAblCCXI0Im8CXzIRMcxxWuEOUJ6AOi/T33Q/Op8IzyL/bL+koC3wj0DtMVshs0IDIjQSRNIoQdIxmJFMkPAQzSBiUCXP8b/in+sf3b/VX+2P7b/+H/nP88/1f+ZP7J/jz+sf7v/kf+M/4z/W77cPnE90b01O5W6QjiPdx81xbSyM94zezJWckJygnKbs080JPNiNOs5G7wRvysCpkOvxU0JsIyljkWOX8zHytMI08fnRb9B9H5cewI4sHd+tug27jcSdxS36bm/uyC9JX6tP41BJcG8QbsCAkMvBDEFcYY4hhaGgkgrCSPKKgqGSdkIkwdoxiuE8wMvgW//Hv1qfFa8PjxI/T197v8QQLLCc0QLBfAHBIgOiEaIMsdgRp5FoASQQ1UB+4C3//C/Sb9/fzZ/Mf8Ef0B/oL+Tv8lADcAwv/D/t7+J/8p/2T/GP67/Dz7v/gO9pXyBu496D7h5tl51ADQdsslyO7E2MKIw3DED8T2x5jTNeIr8ov/7gfqEXIepC1fO/w/uzz5NdowJytzI8gabQwY/Tfy1en74nPfJ99h3Y/dbeH45KbqefDf9LL5wf1AAY0EAgdpCPALHhFfFCgXNxozHDoesSLXJcwkpyJYHqoY2BSOEXIMTAX//U/4CvYS9vL3Ovtr/cgAPAWkCfEO4RNwF1QY4xYeFawS1w+kDfsJtgXRAjcAL/8v/xb/0P9tAK8BJQMfBOsEiASABOQDlQIEArAAMf+1/An6XviF9VLyUu9p6x/nWuNR3rrY4dX80cDMasu6yfbF68WKxZHDq82B3/XooPOeAEkGaRHkJNwzvzgmOCs1hS64K3UqhCExFWQIS/yg8jbsGekO5gzlAeRD4zzn0+lr7V/zwPaM+lr8x/wi/kD/DATiCCsLBA6/D/ESTRgBHSUiuSThJM0kYyJVH9UbEhhVFDAO7wdFAmD9fPy5/Yz/bgEUAngEKwgXDJEQpRKyEiwR2w6vDK0JUQcBBfUBwv83/lX9xP0d/0EBlgP9BLIFSgaYBkIGggWKBJACKQAb/i37FfjO9bfzrPEC79LrgOcB4h3eztsY2YrUfs+Ny8/H+MXFxGvCX8RKzrvbA+YA79/44gH1D2ciQS+uMtwx2jCiLhsulituI9wXhgsyA6772fVk85bwPu5p7F3twu9f8R/0P/Zr9/n3cfho+CH3hvfP+UD85v7bAe8EmAjZDdoUnBt2IHAjViRBJEMk6iMKItIdqRiZE5gO7QqRCG4GSwU8BYYFXAbqB5MJ4wrNCysMyAtJCuMH0ASpAS7/dv0Q/FL6cPmL+Uv6x/yV/+8B7gMTBeUFGQYdBu8FOgW8A68AvP3/+ir4JPbS833w8Oy36Y3lO+JW4GDcv9jY1fHQisxfyWzFa8NfyIPQt9am3vzmhe12+YgJMRfJIGYleSdhKGoqwizmKdoj6xsfE9wMKQd2A2cBj/21+xP7PvpL+0T8ev2P/q7+AP4l+2D4ifYs9YD14/WQ9aT1tfYI+i//3QT4CgoQJxQJGHkbsh6qIHMhqSDvHTEbWBg6FcsSwhASD88NEg0GDY8NfQ53DxoQ1w+oDjoMHwkpBsMCI/8v+yH3tPM88TrwL/AV8Q3zT/Xk93r66/xD/wIBYgLSAjcC6ACe/h78uPlL99j0M/Ij7+frGOn35sPlVuTZ4c7eaNv113LVX9Wr1rfYwdtn3tLhdOck76P32P+MBvsK5A4aE+wWOhkLGrAYWBWdEhYQdA3hC6kKQgkgCKAH3gexCMkJ1ApwCzYLRAqUCGsGRAQDAjQA6f35+lX5PPj197H5K/y9/k0BZASyB7kKJg7PEFwSihMCFL0TuRJ+ERcQWw4mDWwM6AuRC14LWQuQCykMxAznDAcMlQoCCTMHcAV7A+UAEP6e+3X53Pff9hT2sfW59fT1SPbS9mX3H/j2+Gb5pPnL+dv5xfnf+Zb6J/t7+9v7Ffwi/Lf7UvtT+6X6S/nn98v1nPPd8gTynO8i7kHu5e0X7kbvFPBh8Svz2vSw9uz38/hL+lT7Tvwf/V39SP03/YP9//2k/q7/bADBAFoBMgJRA9YE+QUwBhcG4QWVBXsFSgUGBaEEDQSoA4YDxwN+BE0FvwUxBvoGlQcPCIoIvAi3CJQIZggnCOkH4AfiB+4HIAhjCKsI3ggOCUoJYQlRCf4IRghZB04GGQXfA9UC0QHOAA8Abv/j/rr+6P5W/+T/bgDxAC0BGAEWATkBFgHEAEMAcP/S/nb+Wv5t/kf+LP4u/jf+ef7l/in/PP9Q/wz/X/7b/Xz9Cf2h/CX8c/vO+mz6J/r6+fb5APoW+jT6MfoX+hf6OPpo+pD6l/pw+jr6K/os+kT6kvrO+uv6FvtY+8n7SPzL/GH96v1y/uL+Mf93/6n/6f8cADcAVgBLAEQAawCLALMA1gDuADcBewHIATQCgALlAmIDxgMFBDcEagSIBMEE7ATsBPME4ATIBMMExQTQBMEEpgSLBGUETQQ7BCMEHAQTBPkD3wPBA6gDkgN2A2MDSQMTA9UCkAI4Au4BtAFhAQoBtwBLAOz/p/9c/xD/tv5b/hT+4f25/Zn9jv2R/ZD9o/3J/fD9Mf5//sj+D/9M/47/xv/h//r/BQD7/97/qv9v/zD/8P6r/mz+Nv79/dn9v/2y/cD91P3n/QD+JP5C/mL+i/6l/rn+yP7F/sL+zf7S/sn+xP66/qT+mP6O/oT+hP53/mP+XP5Z/lf+XP5c/lT+W/5t/n7+nv7D/uD+B/82/2P/lf/K//3/JQA7AEEAQABJAE8ASwBDADQAIgAcAC4AUgB6AJ4AywADATgBcQGWAasBxAHKAcwByAGuAYsBXQExAQEB0ACkAHIATAAgAP3/7f/S/8f/0P/Y/+L/+/8TACUASABtAIoArADLANwA5gD1AP4A+ADuANgAsQCIAFkAIwDu/7T/bf8k/+L+rP58/lT+Nv4g/hz+IP4m/j3+Yv6P/sP++/4z/2r/oP/R//r/IABCAE8AWgBlAGAAYQBfAFIAQgA3ADgAMgAxAC0AHgAgABwADAAHAP3/7f/c/8v/tP+Y/4L/cP9o/2L/Wf9a/2T/c/+J/6z/0v/9/y8AXQCIALcA6AATATIBSAFdAXABdQF7AYIBcgFhAVEBMgELAeAAuACIAE8AGwDj/6//iv9j/zz/J/8f/xv/HP8t/0f/Yf+P/8j//v8vAFYAggCoAMIA3ADsAO4A7ADlANAAugCjAIkAdgBgAEYAMgAcAAUA8f/h/9D/uv+t/6H/lf+N/4z/k/+j/7n/yf/g//n/EQAxAEYAVwBnAG4AdAB4AHIAagBmAFoARgA6AC8AIAAWABIACAD///f/7f/o/+H/2f/Q/8L/tv+u/6f/nv+T/47/i/+O/4//k/+b/6P/sP+//8z/0//a/+X/7f/2/wEACQAKABEAHwAkACUAJAAjACkAKgAqACUAGwAWAAgA+P/u/+b/3f/O/8b/wf+6/73/vv+8/77/x//V/97/5v/z//3/DwAmACsAOgBKAEcAUgBXAEsASABDADYAKwAfAA8AAwD3/+X/2P/N/8H/uf+x/63/qv+q/6n/qP+q/6z/tf/B/8f/z//d/+r/9/8HABwALAAzAD8ASgBMAEsASQBIAEIAOQA2ACYAFwARAAIA+//2/+r/6P/j/9n/2f/X/9D/0P/R/8v/y//Q/9H/1P/Y/93/4v/n//D//P8DAA0AFAAZACUAKQApAC0ALAAtACsAKAAmACQAGwASAAwABAD6//X/7f/j/97/2f/T/9D/zv/N/83/0f/V/9T/2//j/+b/8f/8/wIADwAZAB0AJAAqAC8ANAA5ADYALgAqACUAGwAUAAoA/f/0/+b/2f/R/8P/u/+3/7L/s/+u/7D/tv+3/8D/yv/P/9r/5f/u//r/BgAOABQAGwAlACcAKgA0ADMALwAwACoAJQAmABsAEwASAAYAAwABAPf/+P/3//b/9P/w//H/8P/x//n/+f/2/wAABAAHABIAEwAXAB8AHwAlACkAJgAlACMAJAAkACEAGgAUABEACAD//wEA/f/1//P/8P/x/+//6f/r/+z/7f/x//P/+P/7//v/AAADAAYADAARABEAEwAXABgAGAAYABUAEAAPAAsABAAEAAEA+v/6//j/9P/z//L/9//5//f//P/9/wAACQAKAAwADwAOAAwADgANAAoADQAJAAYABwAEAAIA/v/+//z/9v/3//H/7f/x/+z/6f/q/+j/6//s/+v/8f/1//T/9f/4//v//v/+////BgAIAAQACQAIAAEABAAKAAoABwAIAAgABgAIAAkABwAHAAgABAADAAcACAAHAAcABwAHAAkABgADAAMAAwAEAAIAAgADAAEABAAFAAUABwAIAAwADgANAA8ADAAMABIAEQAQAA0ADAANAAcAAgAAAAAAAAD+//v/+//3//T/9//2//r//f/7/wAAAwADAAcAEAAOAA8AFwAVAB0AIQAhACgAIwAkACQAIAAiAB0AGQAbABUAFAAXAA8ACgAMAAwACgAHAAcABQADAAIAAQAAAAIABAADAAMABAAEAAIACQAKAAYADAALAAkADAAJAAkACAAFAAMAAAD+////AAD9//f/9//4//b/9//6//r/+v/6//n/+v/9//X/9v/9//T/9v/5//T/9P/0//P/9P/2//f/9//z//j//P/4//z//P/8/wAAAAD+//3///8AAP7/AgAHAAgABQAFAAcAAwAAAAIA//8CAP//+P/5//X/8v/1//X/8v/z//X/9v/3//b/+//9//7/AgAAAAIAAwADAAYAAQAEAAEA+/8BAAEA/v/8//r/9//x/+//7P/q/+r/5v/l/+j/6f/m/+H/4P/i/+T/5v/m/+b/6v/q/+n/7P/p/+r/8P/t/+3/8f/w//H/8P/w/+3/7v/x/+f/5//s/+v/7f/s/+z/7f/t//D/8//0//P/+P/7//3///8CAAcACgAKAAkABwAKAAwADQAPABAADwAOAA0ADgAOAA0ACwALAAoABwAKAA0ADQAKAAkACAAFAAkACwAKAAsADAAPABAADwAPAAwADgAVABUAEgAVABgAFgAUABYAGQAbAB0AHwAZABcAGAAYAB4AHgAaABgAFQATABAAEAATAA8ADwAQAAsACQALAA4ADQAKAAgACAANAA8ACgAJAAoACAAHAAYABgAJAAoABgAHAAkABAD+//3//////wEAAwACAP7/+f/5//r/+f/6//X/8f/y//L/8v/x//H/8v/u/+7/7//r/+n/7P/t/+n/5f/k/+X/4//l/+b/4v/j/+b/6P/p/+j/6P/m/+f/6f/n/+n/6//s/+v/6P/n/+X/5P/n/+b/5//n/+b/5f/k/+P/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\",\"isFinal\":null,\"normalizedAlignment\":{\"chars\":[\" \",\"H\",\"e\",\"y\",\",\",\" \",\"h\",\"o\",\"w\",\" \",\"c\",\"a\",\"n\",\" \",\"I\",\" \",\"h\",\"e\",\"l\",\"p\",\" \",\"y\",\"o\",\"u\",\" \",\"t\",\"o\",\"d\",\"a\",\"y\",\"?\",\" \"],\"charStartTimesMs\":[0,35,81,174,221,255,279,313,348,372,406,441,476,511,546,580,615,650,685,720,755,789,813,836,871,906,929,975,1045,1091,1207,1277],\"charDurationsMs\":[35,46,93,47,34,24,34,35,24,34,35,35,35,35,34,35,35,35,35,35,34,24,23,35,35,23,46,70,46,116,70,163]},\"alignment\":{\"chars\":[\"H\",\"e\",\"y\",\",\",\" \",\" \",\"h\",\"o\",\"w\",\" \",\"c\",\"a\",\"n\",\" \",\"I\",\" \",\"h\",\"e\",\"l\",\"p\",\" \",\"y\",\"o\",\"u\",\" \",\"t\",\"o\",\"d\",\"a\",\"y\",\"?\"],\"charStartTimesMs\":[0,81,174,221,255,279,279,313,348,372,406,441,476,511,546,580,615,650,685,720,755,789,813,836,871,906,929,975,1045,1091,1207],\"charDurationsMs\":[81,93,47,34,24,0,34,35,24,34,35,35,35,35,34,35,35,35,35,35,34,24,23,35,35,23,46,70,46,116,233]}}', extra='')", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:55:37,995", "level": "INFO", "name": "livekit.plugins.elevenlabs", "message": "waiting for 11labs message", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:56:48,664", "level": "WARNING", "name": "livekit.plugins.deepgram", "message": "deepgram connection failed, retrying in 0s", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:57:28,808", "level": "WARNING", "name": "livekit.agents", "message": "job is unresponsive", "delay": 27, "job_id": "AJ_nPJmwytXoBGM", "pid": 88921} {"asctime": "2024-05-20 17:58:03,682", "level": "WARNING", "name": "livekit.plugins.deepgram", "message": "deepgram connection failed, retrying in 2s", "job_id": "AJ_nPJmwytXoBGM", "pid": 88921}

deepgram transcribe quality in livekit much lower than when transcribing on deepgram demo website

please compare the transcribing the accuracy of running the livekit+deepgram agent demo with running the deepgram demo on their website, you will see quality of transcription much higher on deepgram.

deepgram demo:
https://console.deepgram.com/project/<YOUR_PROJECT_ID>/mission/transcribe-your-voice-in-realtime

livekit+agent demo:
https://github.com/livekit/agents/tree/main/livekit-plugins/livekit-plugins-deepgram/livekit/plugins/deepgram

KITT not working - latest master

KITT example is not working throwing this exception:

Exception in thread Thread-2 (_write_thread):
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
{"asctime": "2024-04-13 20:00:42,152", "level": "DEBUG", "name": "root", "message": "process started", "job_id": "AJ_AUFCiWbbBkka", "url": "http://livekit-server.livekit", "pid": 92412}
failed to write log: to_bytes() missing required argument 'byteorder' (pos 2)
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/venv/lib/python3.10/site-packages/livekit/agents/apipe.py", line 49, in _write_thread
    ipc_enc.write_msg(self._p, msg)
  File "/venv/lib/python3.10/site-packages/livekit/agents/ipc_enc.py", line 45, in write_msg
    b.write(msg.MSG_ID.to_bytes(4))
TypeError: to_bytes() missing required argument 'byteorder' (pos 2)

error when running the examples on codespaces

When I try to run the voice assistant example on github codespaces, upon the execution of python minimal_assistant.py download-files
I get the following error :

python minimal_assistant.py download-files
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Downloading files for <livekit.plugins.deepgram.DeepgramPlugin object at 0x7b7d8a435030>"}
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Finished downloading files for <livekit.plugins.deepgram.DeepgramPlugin object at 0x7b7d8a435030>"}
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Downloading files for <livekit.plugins.elevenlabs.ElevenLabsPlugin object at 0x7b7d8a436050>"}
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Finished downloading files for <livekit.plugins.elevenlabs.ElevenLabsPlugin object at 0x7b7d8a436050>"}
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Downloading files for <livekit.plugins.openai.OpenAIPlugin object at 0x7b7d8a436e60>"}
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Finished downloading files for <livekit.plugins.openai.OpenAIPlugin object at 0x7b7d8a436e60>"}
{"asctime": "2024-05-27 18:26:13,005", "level": "INFO", "name": "livekit.agents", "message": "Downloading files for <livekit.plugins.silero.SileroPlugin object at 0x7b7d89471ba0>"}
Using cache found in /home/codespace/.cache/torch/hub/snakers4_silero-vad_master
Traceback (most recent call last):
  File "/workspaces/agents/examples/voice-assistant/minimal_assistant.py", line 43, in <module>
    cli.run_app(WorkerOptions(request_fnc))
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/livekit/agents/cli/cli.py", line 191, in run_app
    cli()
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/livekit/agents/cli/cli.py", line 188, in download_files
    plugin.download_files()
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/livekit/plugins/silero/__init__.py", line 29, in download_files
    _ = torch.hub.load(
  File "/home/codespace/.local/lib/python3.10/site-packages/torch/hub.py", line 568, in load
    model = _load_local(repo_or_dir, model, *args, **kwargs)
  File "/home/codespace/.local/lib/python3.10/site-packages/torch/hub.py", line 594, in _load_local
    hub_module = _import_module(MODULE_HUBCONF, hubconf_path)
  File "/home/codespace/.local/lib/python3.10/site-packages/torch/hub.py", line 106, in _import_module
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/codespace/.cache/torch/hub/snakers4_silero-vad_master/hubconf.py", line 5, in <module>
    from utils_vad import (init_jit_model,
  File "/home/codespace/.cache/torch/hub/snakers4_silero-vad_master/utils_vad.py", line 2, in <module>
    import torchaudio
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/torchaudio/__init__.py", line 2, in <module>
    from . import _extension  # noqa  # usort: skip
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/torchaudio/_extension/__init__.py", line 38, in <module>
    _load_lib("libtorchaudio")
  File "/usr/local/python/3.10.13/lib/python3.10/site-packages/torchaudio/_extension/utils.py", line 60, in _load_lib
    torch.ops.load_library(path)
  File "/home/codespace/.local/lib/python3.10/site-packages/torch/_ops.py", line 1032, in load_library
    ctypes.CDLL(path)
  File "/usr/local/python/3.10.13/lib/python3.10/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libtorch_cuda.so: cannot open shared object file: No such file or directory

Anyone knows the cause behind this ?

Can clients re-use token after disconnect?

I recently used livekit for my application using agents example. And I had a problem:

What happended?

I use Android application to connect to livekit with genereated token and wss url, everything is okay. Then I disconnect my client from livekit using room.disconnect(). I saw that my agents still running for this room. After that, I reconnect using the same token and I only see a black screen.
In server side I saw this log:

{"asctime": "2024-04-25 09:11:32,833", "level": "ERROR", "name": "livekit.agents", "message": "livekit_api::signal_client::signal_stream:178:livekit_api::signal_client::signal_stream - unhandled websocket message Err(Protocol(ResetWithoutClosingHandshake))", "job_id": "AJ_8oNxanmAa5c2", "pid": 133}
{"asctime": "2024-04-25 09:11:32,837", "level": "DEBUG", "name": "livekit", "message": "livekit::rtc_engine:377:livekit::rtc_engine - engine task closed"}
{"asctime": "2024-04-25 09:11:32,837", "level": "DEBUG", "name": "livekit", "message": "livekit::room:943:livekit::room - disconnected from room: UnknownReason"}

What I expected:

I can re-use the token from client to re-connect to the room.
Please help,
Thanks!

elevenlabs-plugin: "cloned" + "professional" voices not working

With the minimal_assistant.py example, the above categories of voices don't seem to generate output properly. Instead it seems to hang for long periods of time.

Am seeing LLM chat completion requests completing successfully, which seems to suggest that STT and OpenAI are working, but no audio output.

I'm using a Macbook with M1 / Ventura 13.0.1, running Python 3.12.

elevenlabs-plugin is working correctly with "premade" voices, and also with OpenAI's TTS (though it doesn't support streaming)

Examples of non-working code:

Voice = elevenlabs.Voice(
    id=MY_VOICE_ID,
    name="Voice Name",
    category="professional",
    settings=elevenlabs.VoiceSettings(
        stability=0.60, similarity_boost=1.0
    )
)

assistant = VoiceAssistant(
  vad=silero.VAD(),
  stt=deepgram.STT(),
  llm=openai.LLM(),
  tts=elevenlabs.TTS(voice=Voice),
  chat_ctx=initial_ctx,
)
assistant.start(ctx.room)

As well as:

Voice = elevenlabs.Voice(
    id=MY_VOICE_ID,
    name="Voice Name",
    category="cloned",
    settings=elevenlabs.VoiceSettings(
        stability=0.60, similarity_boost=1.0
    )
)

assistant = VoiceAssistant(
  vad=silero.VAD(),
  stt=deepgram.STT(),
  llm=openai.LLM(),
  tts=elevenlabs.TTS(voice=Voice),
  chat_ctx=initial_ctx,
)
assistant.start(ctx.room)

What I'm seeing in logs from agent running locally:

2024-05-14 01:56:21,398 INFO  httpx  HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"	  job_id=AJ_oiddbfaSEWxh pid=56250
2024-05-14 01:56:22,141 INFO  httpx  HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"	  job_id=AJ_oiddbfaSEWxh pid=56250
2024-05-14 01:56:23,720 ERROR  livekit.plugins.elevenlabs  11labs connection failed
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/livekit/plugins/elevenlabs/tts.py", line 365, in _run_ws
    await asyncio.gather(send_task(), recv_task())
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/livekit/plugins/elevenlabs/tts.py", line 340, in recv_task
    raise Exception("11labs connection closed unexpectedly")
Exception: 11labs connection closed unexpectedly
	  job_id=AJ_oiddbfaSEWxh pid=56250
2024-05-14 01:56:32,020 INFO  httpx  HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"	  job_id=AJ_oiddbfaSEWxh pid=56250
2024-05-14 01:56:33,258 ERROR  livekit.plugins.elevenlabs  11labs connection failed
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/livekit/plugins/elevenlabs/tts.py", line 365, in _run_ws
    await asyncio.gather(send_task(), recv_task())
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/livekit/plugins/elevenlabs/tts.py", line 340, in recv_task
    raise Exception("11labs connection closed unexpectedly")
Exception: 11labs connection closed unexpectedly
	  job_id=AJ_oiddbfaSEWxh pid=56250

Happy to share more context as needed - awesome project!

Elevenlabs should work for Free and Starter price tiers

The ElevenLabs plugin was written when PCM audio was supported in lower price tiers. Now it looks like only mp3 audio is supported in the lower price tiers.

Our default implementation currently doesn't work. This issue represents:

  1. The ElevenLabs Plugin should support for the mp3 output formats
  2. The default for the ElevenLabs should be an output format supported by the lowest price tier

Hidden agent can not publish audio track

A hidden agent will not publish its audio track and have other participants subscribe to it. Other real participants do not automatically subscribe to this track and do not receive track publish events. If the agent is marked not hidden / or visible, then the tracks publish correctly and the other participants automatically subscribe to them. I imagine most use cases will be for the agent to be hidden. Is this a bug or by design? For a use case we are looking at, it would be great to have this functionality.

ideo Frame Not Appearing in Livekit Playground on Mac M3 - Agent Status Stuck at "Starting"

Hi I'm trying to test the playground with agent but the video frame doesn't appear somehow. It shows dark green color on the video section. And Agent connection True but agent status is "starting" forever.
Here is my code for agent. I'm using mac M3.
import logging
from livekit import rtc
from livekit.agents import JobContext, JobRequest, WorkerOptions, cli

WIDTH = 640
HEIGHT = 480

async def entrypoint(job: JobContext):
room = job.room
source = rtc.VideoSource(WIDTH, HEIGHT)
track = rtc.LocalVideoTrack.create_video_track("video", source)
options = rtc.TrackPublishOptions(source=rtc.TrackSource.SOURCE_CAMERA)
publication = await room.local_participant.publish_track(track, options)
logging.info("published track", extra={"track_sid": publication.sid})

async def request_fnc(req: JobRequest) -> None:
logging.info("received request %s", req)
await req.accept(entrypoint)

if name == "main":
from dotenv import load_dotenv
import os

load_dotenv()

LIVEKIT_API_KEY = os.getenv("LIVEKIT_API_KEY")
LIVEKIT_API_SECRET = os.getenv("LIVEKIT_API_SECRET")
LIVEKIT_URL = os.getenv("NEXT_PUBLIC_LIVEKIT_URL")
cli.run_app(WorkerOptions(request_fnc=request_fnc, api_key=LIVEKIT_API_KEY, api_secret=LIVEKIT_API_SECRET,ws_url=LIVEKIT_URL))

Could someone help?

Elevenlabs TTS websocket connection design

Hi,

I was able to make the minimal_assistant.py implementation work. Once I sorted out all the difficulties, it runs pretty well! Kudos for that 😃.

I have a question regarding the WebSocket connections used in the ElevenLabs TTS module. In my environment, I noticed that the WebSocket creation is being triggered every time the agent responds to the user. Consequently, the WebSocket is being closed every time the agent stops talking.

Questions:

  • Is this a design decision? If so, could you please explain the rationale behind it?

  • Is there a specific reason for not maintaining a persistent WebSocket connection throughout the session?

I believe closing and reopening the WebSocket repeatedly introduces unnecessary overhead. Maintaining one or a few stable connections throughout the session might be more efficient.

Looking forward to your insights on this.

Thank you!

openai.tts with StreamAdapter has some bugs

The experience with this SDK is a bit poor

1、elevenlabs tts.py line:333, if meet api error, please take a log. @MichaelYang1995 china area can't visit elevenlabs, with VPN only use paid elevenlabs API. image be a paid api user to try.

2、openai.tts with StreamAdapter has some bugs, if you follow agent quick-start doc, and use follow code:

openai_tts = openai.TTS(
            model=openai.TTSModels, 
            voice=openai.TTSVoices)
    vad = silero.VAD()
    vad_stream = vad.stream(min_silence_duration=1.0)
    tts = agents.tts.StreamAdapter(openai_tts, vad_stream)

you will got some error like VADStream has no attribute 'stream', from file: livekit/agents/voice_assistant/assistant.py:728 @keepingitneil it's a code bug right? i want to use openai.tts-1 not elevenlabs, how to fix it ?

Feature Request: Node.js Environment Support for LiveKit Agents

Feature Details:

Node.js SDK Integration: Develop a dedicated Node.js SDK for LiveKit, providing developers with native access to LiveKit functionalities within their Node.js environments. This SDK should offer comprehensive coverage of LiveKit features, ensuring parity with existing SDKs.
NPM Package: Publish the Node.js SDK as an NPM package, facilitating easy installation and dependency management for Node.js projects. This approach aligns with established Node.js development practices and enhances the accessibility of LiveKit within the Node.js ecosystem.
Comprehensive Documentation: Furnish extensive documentation specifically tailored for Node.js developers, offering clear guidance on integrating and utilizing LiveKit functionalities within Node.js applications. This documentation should include code examples, best practices, and troubleshooting tips to streamline the development process.
Support for Node.js Frameworks: Ensure compatibility with popular Node.js frameworks such as Express.js, NestJS, and Fastify, enabling developers to seamlessly integrate LiveKit into their existing projects without friction. Compatibility with these frameworks enhances flexibility and fosters rapid development.
Event Emitters and Promises: Leverage Node.js conventions such as event emitters and promises to provide an intuitive and asynchronous programming model for interacting with LiveKit APIs. This approach aligns with Node.js development paradigms and enhances the developer experience when working with LiveKit in Node.js environments.
Community Engagement: Actively engage with the Node.js developer community through forums, social media, and developer outreach programs to solicit feedback, address concerns, and foster a vibrant ecosystem around LiveKit in Node.js. Incorporating community feedback ensures that the Node.js SDK evolves in alignment with developer needs and industry trends.
Benefits:

Expanded Developer Reach: By supporting Node.js environments, LiveKit can attract a broader range of developers who prefer Node.js for their real-time communication projects, thereby increasing its user base and fostering community growth.
Enhanced Developer Experience: Node.js developers can leverage their existing skills and familiarity with the Node.js ecosystem to seamlessly integrate LiveKit into their projects, resulting in a more streamlined development experience.
Ecosystem Synergy: Integration with Node.js opens up opportunities for collaboration and integration with other Node.js libraries and frameworks, enriching the LiveKit ecosystem and enabling developers to leverage a wider range of tools and resources.
Conclusion:
Introducing native support for Node.js environments within LiveKit represents a significant opportunity to expand the platform's reach, enhance developer experience, and foster ecosystem growth. By embracing Node.js, LiveKit can empower a new wave of developers to build innovative real-time communication applications while enriching the overall developer community.

Adding timestamp (+ customizable logging configuration?) to worker logging

Currently, worker.py does not offer an easy way to customize log formats, particularly to include timestamps in logs for debugging. This makes it difficult to debug our worker deployment.

Feature request
Add logging functionality to allow users to customize the log format, either by allowing users to use custom logger or simply adding another CLI flag to toggle timestamps in logs.

Questions for maintainers

  • Have you considered adding timestamps to worker logging?
  • Is there a specific approach you prefer?

Re-join the room after agent server restarted

Currently, if agent server were restarted, all agents of joined rooms would be disconnected. Is there any way to make the agent re-join the room, or to invite the agent to the room actively?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.