diff --git a/README.md b/README.md index bed89ec..7392fce 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,9 @@ sharklocal/ ├── client.py # VacuumClient — unified entry point with transport selection ├── rest_client.py # RESTVacuumClient — async HTTPS/HTTP client (aiohttp) ├── mqtt_client.py # MQTTVacuumClient — async MQTT client (aiomqtt) -├── protobuf.py # Pure-Python schema-free protobuf decoder -├── models.py # VacuumStatus, VacuumEvent, DeviceInfo, VacuumMode +├── protobuf.py # Pure-Python schema-free protobuf codec +├── vacuum_map.py # Map / room / trajectory decoding and room-command encoding (MQTT) +├── models.py # VacuumStatus, VacuumMap, VacuumEvent, DeviceInfo, VacuumMode ├── exceptions.py # Typed exception hierarchy └── mappings/ ├── __init__.py # load_* / list_* utilities @@ -155,6 +156,23 @@ All transport clients return normalized model objects. See [docs/data-models.md] --- +## Maps, Rooms and Settings (MQTT) + +On models that publish map frames, monitoring yields the live map (occupancy grid, cleaned path, robot pose with heading) every few seconds during a job, and a persisted map (rooms, wall and door vectors, dock pose, job statistics, the robot's event log) each time the robot docks. The `sharkiq_v1` MQTT mapping also exposes suction level, find-robot and the Recharge & Resume / Evac & Resume settings, and `VacuumClient` can start room, Matrix and spot cleans. + +```python +async with VacuumClient("192.168.1.100", mqtt_mappings="sharkiq_v1") as vacuum: + vacuum.on_status_update(lambda s: s.map and print(s.map.robot, len(s.map.path))) + await vacuum.start_monitoring() + + await vacuum.set_suction(SuctionLevel.MAX) + await vacuum.clean_rooms(["Kitchen"], deep=True) # needs vacuum.last_map (persisted) +``` + +See [docs/vacuum-client.md](docs/vacuum-client.md#maps-rooms-and-settings) and the `VacuumMap` section of [docs/data-models.md](docs/data-models.md). + +--- + ## Mapping Configuration See [docs/mapping-configuration.md](docs/mapping-configuration.md) for annotated YAML examples for both transports, the full field reference, instructions for adding support for a new model, and how to register a custom MQTT decoder. @@ -209,6 +227,10 @@ The minimum required coverage is **95%**. All PRs must pass before merging. See - The `status_water_tank_removed` event type is fired for dustbin removal on vacuums, not only water tank removal on mops. Handle accordingly in Home Assistant event translation. - The `/get/robot_id` endpoint does not expose a serial number. Use the `mac_address` from `/get/wifi_status` as the device `unique_id`. - MQTT `go_home` and `stop` send identical payloads in the `sharkiq_v1` mapping — both issue the protobuf stop-and-return command. +- The SharkClean app bundles a suction change into its start and dock messages. The `sharkiq_v1` mapping sends the bare job commands, so `start_cleaning` and `go_home` leave the suction setting alone. +- The suction level is not reported in MQTT status; the robot echoes a change once (field 8) and is then silent about it. Remember the last level you set. +- Room and spot cleans re-upload the map's room definition, names included. Build them from the latest persisted map (`VacuumClient.last_map`) or a stale one renames rooms. +- On the RV2610BFCA, `BatteryInfo.ChargingState` is `3` in every frame, so `charging` is `True` mid-clean. Use `mode` to decide whether the robot is docked. - The REST API uses a self-signed TLS certificate. SSL verification is disabled in the `sharkiq_v1` mapping (`verify_ssl: false`). - The REST `charging` field returns `"connected"` or `"unconnected"` as strings, not a boolean. The library normalises this to `True`/`False` on `VacuumStatus.charging`. - The REST `mode` field alone is insufficient to determine if a vacuum is docked. `mode: "ready"` with `charging: "connected"` means docked (`VacuumMode.DOCKED`); `mode: "ready"` with `charging: "unconnected"` means the vacuum is stopped but off the dock (`VacuumMode.IDLE`). This combined evaluation is handled automatically by the library. diff --git a/docs/cli.md b/docs/cli.md index b550edf..5b95c9a 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -52,4 +52,6 @@ Send a specific command via a chosen transport (defaults to `mqtt`): python -m sharklocal --cmd dock --transport mqtt ``` -Available commands: `start`, `stop`, `dock`, `status`, `events`, `info`. +Available commands: `start`, `stop`, `dock`, `status`, `events`, `info`, `find`, `suction-eco`, `suction-normal`, `suction-max`, `recharge-resume-on`, `recharge-resume-off`, `evac-resume-on`, `evac-resume-off`. + +The settings and `find` commands exist only in the MQTT mapping. While `--monitor` is running, any status update that carries map data prints an extra `[MAP]` line with the grid size, the number of cleaned-path points, the robot's pose and the room names (persisted map only). diff --git a/docs/compatibility/rv2610bfca.md b/docs/compatibility/rv2610bfca.md index e1eb009..6b3f77f 100644 --- a/docs/compatibility/rv2610bfca.md +++ b/docs/compatibility/rv2610bfca.md @@ -1,4 +1,4 @@ -# RV2610BFCA — Compatibility Matrix +# RV2610BFCA (Shark Matrix Plus) — Compatibility Matrix --- @@ -9,11 +9,23 @@ | Start cleaning | ❌ | ✅ | MQTT: `sharkiq_v1` | | Stop | ❌ | ✅ | MQTT: `sharkiq_v1` | | Return to dock | ❌ | ✅ | MQTT: `sharkiq_v1` | -| Explore / Map | ❌ | ❌ | | +| Explore / Map | ❌ | 🟡 ³ | MQTT: `sharkiq_v1` | | Get status | ❌ | ✅ | MQTT: `sharkiq_v1` | -| Get event log | ❌ | ❌ | | +| Get event log | ❌ | ✅ ¹ | MQTT: `sharkiq_v1` | | Get robot ID | ❌ | ❌ | | | Get Wi-Fi status | ❌ | ❌ | | +| Find robot | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Set suction (eco / normal / max) | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Recharge & Resume on / off | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Evac & Resume on / off | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Clean rooms (incl. Matrix Clean) | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Spot clean | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Pause / resume | ❌ | 🟡 ³ | MQTT: `sharkiq_v1` | +| Do not disturb, volume | ❌ | 🟡 ³ | MQTT: `sharkiq_v1` | + +> ¹ Via the event log embedded in the persisted map frame the robot publishes when it docks (`VacuumMap.log`), not via a request. Entries are also streamed during a job (`VacuumStatus.log_entries`). +> +> ³ Sent in the same format as the verified commands, but not yet run on this robot. --- @@ -23,7 +35,23 @@ |-------|:----:|:----:|--------------------| | Operating mode | ❌ | ✅ | MQTT: `sharkiq_v1` | | Battery level | ❌ | ✅ | MQTT: `sharkiq_v1` | -| Charging status | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Charging status | ❌ | ✅ ² | MQTT: `sharkiq_v1` | +| Job active / deep clean | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Recharge & Resume / Evac & Resume | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Warnings active now | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Faults active now | ❌ | 🟡 ⁴ | MQTT: `sharkiq_v1` | +| Temperature, Wi-Fi state | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Suction / brushroll / side-brush motor speeds | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Live map (grid, cleaned path, robot pose with heading) | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Persisted map (rooms, room raster, walls, doors, dock, cleaned area, clean time, event log) | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Persisted map on request (`request_map`: the same, less the event log) | ❌ | ✅ | MQTT: `sharkiq_v1` | +| Firmware versions | ❌ | ✅ ⁵ | MQTT: `sharkiq_v1` | + +> ² Derived from the robot's system state (charging on the dock). The device-info field once read as a charging state is the Wi-Fi state: it reads `3` in every frame, including mid-clean. +> +> ⁴ Decoded from the status frame; no fault occurred during testing, so not yet seen with a value. +> +> ⁵ From the event log (`DT_VERSION_L01`, `DT_VERSION_MCU`). --- @@ -33,17 +61,26 @@ |------|:----:|:----:|--------------------| | `cleaning` | ❌ | ✅ | MQTT: `sharkiq_v1` | | `returning_to_dock` | ❌ | ✅ | MQTT: `sharkiq_v1` | -| `docking` | ❌ | ✅ | MQTT: `sharkiq_v1` | +| `docking` | ❌ | ❌ | | | `docked` | ❌ | ✅ | MQTT: `sharkiq_v1` | | `idle` | ❌ | ❌ | | +| `paused` | ❌ | ✅ | MQTT: `sharkiq_v1` | +| `error` | ❌ | ❌ | | | `exploring` | ❌ | ❌ | | --- ## Known Issues / Notes +- **Robot type:** `lidar` in `sharklocal.compat` terms, with a self-emptying dock. The retail SKU is not in the SharkClean app's model table (the app keys it by the robot's cloud model string); the firmware line (`P7`) is the app's Three60 lidar platform. - **REST API:** Port 443 is closed/refused. Port 80 is open, but `/get/status` and `/get/wifi_status` return `404 Not Found`, and `/` returns a forbidden HTML page. -- **MQTT:** Uses standard `sharkiq_v1` protobuf format. Status requests, passive monitoring, and basic commands work. -- **Observed MQTT status:** `mode=docked`, `battery_level=100`, `charging=true`. -- **Command test:** `start_cleaning` returned `True` and status changed to `cleaning` within about 2 seconds. `stop` returned `True` and status changed to `returning_to_dock` within about 2 seconds. `go_home` returned `True`; the robot reported `docked` about 28 seconds after the first return-to-dock command. -- **Command caveat:** In the current `sharkiq_v1` MQTT mapping, `stop` and `go_home` use the same payload, so both appear to initiate return-to-dock behavior on this model. +- **MQTT:** Uses standard `sharkiq_v1` protobuf format. Status requests, passive monitoring, and commands work. +- **Command test:** `start_cleaning` returned `True` and status changed to `cleaning` within about 2 seconds. `stop` returned `True` and status changed to `returning_to_dock` within about 2 seconds. `go_home` returned `True`; the robot reported `docked` about 28 seconds after the first return-to-dock command. Room clean, Matrix room clean and spot clean each cleaned the right area and returned to the dock on their own. +- **Lifecycle** (firmware `V6.6.10-P7.N3308.17.0`): battery full on the dock (`14`) → cleaning (`6`) → returning (`7`) → charging on the dock (`13`) → battery full (`14`). The persisted map frame is published as it reaches the dock. State `4` (paused) is reported when stopped off the dock or lifted. +- **Suction:** accepted while docked (the app only greys the control out). Echoed once on change; no status field. +- **Battery:** counts down through a job and snaps back to 100 within seconds of docking. +- **Maps:** a ~27 KB live frame every ~4 s during a job (0.06 m grid, cleaned path, pose log with heading); a ~92 KB persisted frame on docking with rooms, room-id raster, wall/door polylines, dock pose, job start time and the event log. Cleaned floor is marked `0x00` in the grid (every point of the cleaned path lands on one), and the log's `DT_*_CLEAN_TIME` entries give the time spent cleaning. The persisted frame's field 11 also carries two counters that look like a duration and a cell count, but they barely move between different jobs, so they are not decoded. +- **Spot clean:** the robot keeps the spot square in its saved map as a room named `PinDrop`, marked as the room the last job cleaned. `VacuumMap.named_rooms` leaves it out. +- **Warnings:** a dark room reports `WARN_LOW_LIGHT` live and logs `WARN_MM_LOWLIGHT` for the job. +- **Room commands re-upload the room definition**, names included. Build them from the latest persisted map. +- **Single map only:** every map seen carried one floor; the app's rules give multi-floor maps only to newer lines. diff --git a/docs/data-models.md b/docs/data-models.md index a38eff8..522ddd6 100644 --- a/docs/data-models.md +++ b/docs/data-models.md @@ -33,6 +33,8 @@ class VacuumMode(str, Enum): DOCKED = "docked" IDLE = "idle" # Stopped and off the dock (mode=ready, charging=unconnected) EXPLORING = "exploring" # Mapping/exploration run in progress + PAUSED = "paused" # A job paused mid-way (SharkIQ MQTT) + ERROR = "error" # Stopped by a fault (SharkIQ MQTT) ``` The REST API does not expose `docked` directly. `DOCKED` is derived automatically from two fields: @@ -75,3 +77,141 @@ class DeviceInfo: ``` > **Note:** The MAC address returned by `get_wifi_status()` is the recommended value to use as `unique_id` when configuring a Home Assistant device. The robot ID endpoint does not expose a serial number. + +--- + +## SuctionLevel + +```python +class SuctionLevel(str, Enum): + ECO = "eco" + NORMAL = "normal" + MAX = "max" +``` + +Named as in the SharkClean app. Used by `VacuumClient.set_suction()`. + +--- + +## VacuumStatus — MQTT-only fields + +The SharkIQ MQTT status decoder fills in a few more fields; other transports leave them `None`: + +```python +job_active: bool | None # A job is in progress +deep_clean: bool | None # Matrix / spot clean in progress (only set during a job) +recharge_resume: bool | None # Recharge & Resume setting +evac_resume: bool | None # Evac & Resume setting +map: VacuumMap | None # Only on map-bearing frames +``` + +The suction level is deliberately absent: the robot does not report it in status, only echoes it once when it changes. + +--- + + +`errors` and `warnings` are the codes active right now (SharkIQ status fields 5 and 6, repeated). They are numbers; `sharklocal.codes` names them (`codes.names(codes.ERROR_CODES, status.errors)`), with the robot's own enum names — the same names its event log writes as strings (`WARN_MM_LOWLIGHT`, `DE_USR_CTR_DOCK`). `codes.SYSTEM_STATES` names the state behind `mode` (field 4) and `codes.DOCK_EVENTS` the dock reasons. + +## VacuumMap + +Decoded from the map frames the robot publishes over MQTT. Live frames arrive every few seconds during a job; the *persisted* frame arrives once, as the robot reaches the dock, and carries everything the live frame does plus rooms, vectors, the dock pose, job statistics and the robot's event log. + +```python +@dataclass +class VacuumMap: + grid: MapGrid + path: list[MapPoint] # Cleaned path so far, ~1 point per 0.12 m + poses: list[MapPose] # Pose log with heading, ~1 pose per 0.22 m + persisted: bool # True for the saved map: the end-of-job frame or a requested one + report: bool # True for the end-of-job frame only (the one with the event log) + map_id: str | None # e.g. "3CDBBC59" — persisted only + name: str | None # persisted only + dock: MapPose | None # persisted only + rooms: list[MapRoom] # persisted only + features: list[MapFeature] # persisted only: wall "edge" and "door" polylines + log: list[VacuumLogEntry] # persisted only: the robot's event log + job_started: int | None # Unix epoch seconds — persisted only + job_minutes: int | None # whole minutes of the job, docking included — persisted only + raw: dict + + @property + def robot(self) -> MapPose | None: ... # last pose, i.e. where the robot is + @property + def cleaned_area(self) -> float: ... # m² covered by the job: grid.cleaned_cells × resolution² + @property + def clean_time(self) -> int | None: ... # s spent cleaning, summed from the log's DT_*_CLEAN_TIME entries + @property + def named_rooms(self) -> list[MapRoom]: ... # rooms without the spot zone + @property + def spot(self) -> MapRoom | None: ... # the saved spot zone ("PinDrop"), if any +``` + +All coordinates are metres in the map frame; headings are radians, `0` along +x, anticlockwise positive. Convert to grid cells with `col = (x - grid.origin.x) / grid.resolution` and `row = (y - grid.origin.y) / grid.resolution`; row 0 is the bottom of the map. + +A Spot Clean is sent as an extra room named `"PinDrop"` (a ~1.5 m square, `vacuum_map.spot_polygon(x, y)`), and the robot keeps it in its saved map afterwards, marked `selected` — so `rooms` can contain it. `named_rooms` leaves it out, and room and spot cleaning never re-upload it. + +The persisted map is only published when the robot docks, yet room and spot cleaning need it at any time. `map.to_dict()` returns a JSON-serialisable form (rasters base64-encoded, `raw` dropped) and `VacuumMap.from_dict(data)` rebuilds it, so a caller can store the latest persisted map and still clean rooms after a restart. + +### MapGrid + +```python +@dataclass +class MapGrid: + resolution: float # metres per cell (0.06 on the RV2610BFCA) + width: int + height: int + origin: MapPoint # world position of cell (0, 0) + cells: bytes # width × height occupancy values, row-major + room_ids: bytes | None # persisted only: room segment id per cell, 0 = unassigned + + UNKNOWN = 0x4B # unexplored + CLEANED = 0x00 # floor covered by the job + + @staticmethod + def is_wall(value: int) -> bool: ... # 0x50 and above + @staticmethod + def is_floor(value: int) -> bool: ... # explored free floor, cleaned or not + @staticmethod + def is_cleaned(value: int) -> bool: ... # CLEANED + @property + def cleaned_cells(self) -> int: ... + def cell(self, col: int, row: int) -> int: ... + def room_id(self, col: int, row: int) -> int | None: ... +``` + +### MapPoint, MapPose, MapRoom, MapFeature, VacuumLogEntry + +```python +@dataclass +class MapPoint: + x: float + y: float + +@dataclass +class MapPose: + x: float + y: float + heading: float # radians + +@dataclass +class MapRoom: + name: str # as shown in the app + polygon: list[MapPoint] # bounding polygon drawn in the app + selected: bool # included in the most recent job + coverage: float | None # fraction cleaned in the most recent job + +@dataclass +class MapFeature: + kind: str # "edge" (wall outline) or "door" + points: list[MapPoint] + +@dataclass +class VacuumLogEntry: + key: str # e.g. "DT_STATE_CHANGE", "DT_WARNING_CODE" + time: int # Unix epoch seconds, as reported by the robot + code: str # e.g. "SYS_ST_CLEANING", "WARN_MM_LOWLIGHT" +``` + +Room segment ids in `room_ids` do not necessarily map one-to-one onto `rooms`: the robot segments the floor itself, and the app's named rooms are polygons drawn over those segments (two named rooms can share one segment). Use the polygons to name a location and the raster to colour it. + +The event log's `time` values can jump when the robot re-syncs its clock mid-job; rely on list order, not `time`, for sequence. diff --git a/docs/mapping-configuration.md b/docs/mapping-configuration.md index d33e982..a543d83 100644 --- a/docs/mapping-configuration.md +++ b/docs/mapping-configuration.md @@ -69,6 +69,7 @@ status_decoder: sharkiq_protobuf_v1 # Maps protobuf OperatingMode integers to normalized VacuumMode strings modes: + 4: idle 6: cleaning 7: returning_to_dock 13: docking @@ -77,7 +78,11 @@ modes: actions: start_cleaning: type: command # Fire-and-forget MQTT publish - payload: "OgQKAhBLgAEJ" + payload: "gAEJ" + + set_suction_max: # Settings are commands too; the robot echoes them in field 8 + type: command + payload: "OgQKAhBk" get_status: type: status_request # Publish then wait for a response message @@ -90,6 +95,8 @@ actions: - `command` — publishes the payload and returns `True` - `status_request` — publishes the payload, then subscribes and waits up to `timeout` seconds for the first response; returns the decoded `VacuumStatus` +Commands whose payload depends on state — room and spot selection carry the map's room definition — are not mapping actions. They are built at runtime by `sharklocal.vacuum_map` and published with `MQTTVacuumClient.send()`; `VacuumClient.clean_rooms()` / `clean_spot()` wrap that. + --- ## Listing and Loading Mappings diff --git a/docs/mappings.md b/docs/mappings.md index 097a1c8..d607015 100644 --- a/docs/mappings.md +++ b/docs/mappings.md @@ -31,10 +31,17 @@ The table below shows which features are available per transport for the built-i | Stop (pause) | ✅ | ✅ | | Return to dock | ✅ | ✅ | | Explore / map room | ✅ | ❌ | +| Find robot | ❌ | ✅ | +| Suction level (eco / normal / max) | ❌ | ✅ | +| Recharge & Resume, Evac & Resume | ❌ | ✅ | +| Clean rooms / Matrix Clean / spot clean | ❌ | ✅ ² | | **Status** | | | | Polling status (mode + battery) | ✅ | ✅ | | Real-time status (mode) | ❌ | ✅ | -| Event log | ✅ | ❌ | +| Job active, deep clean, settings | ❌ | ✅ | +| Live map (grid, cleaned path, robot pose) | ❌ | ✅ | +| Persisted map (rooms, walls, doors, dock, job stats) | ❌ | ✅ ³ | +| Event log | ✅ | ✅ ³ | | **Device info** | | | | Firmware version | ✅ | ❌ | | MAC address / unique ID | ✅ | ❌ | @@ -45,7 +52,7 @@ The table below shows which features are available per transport for the built-i | Returning to dock | ✅ | ✅ | | Docking | ❌ | ✅ | | Docked (calculated) | ✅ ¹ | ✅ | -| Idle / stopped off dock (calculated) | ✅ ¹ | ❌ | +| Idle / stopped off dock | ✅ ¹ | ✅ | | Exploring / mapping | ✅ | ❌ | | **Connection** | | | | Protocol | HTTPS | MQTT | @@ -53,10 +60,14 @@ The table below shows which features are available per transport for the built-i | SSL | Self-signed (verify disabled) | None | > ¹ `DOCKED` and `IDLE` are derived from the combination of `mode` and `charging` fields in the REST response — neither is reported directly by the API. Charging reports connected or not connected, not active charging of the battery. +> +> ² Built at runtime from the persisted map's room definition (`VacuumClient.clean_rooms()` / `clean_spot()`), not a fixed mapping action. +> +> ³ Carried by the persisted map frame the robot publishes when it docks, available through monitoring (`VacuumStatus.map`). `VacuumClient.request_map()` makes the robot publish it again, without the event log. **Recommendations:** -- Configure **both transports** (`rest_mappings` + `mqtt_mappings`) to get full feature coverage: REST for device info, events, and explore; MQTT for real-time monitoring and docking state. -- If only one transport is available, **REST** provides broader feature coverage. **MQTT** is the better choice when real-time status updates without polling are required. +- Configure **both transports** (`rest_mappings` + `mqtt_mappings`) to get full feature coverage: REST for device info and explore; MQTT for real-time monitoring, maps, rooms and settings. +- If only one transport is available, **MQTT** now provides the broader feature coverage on models that publish map frames, and is the only source of real-time status. **REST** remains the only source of device info (firmware, MAC address) where it is reachable. - Use `probe()` when the correct mapping is not known ahead of time. --- diff --git a/docs/vacuum-client.md b/docs/vacuum-client.md index f5181ca..5bdeca2 100644 --- a/docs/vacuum-client.md +++ b/docs/vacuum-client.md @@ -98,6 +98,17 @@ print(vacuum.via) # "REST", "MQTT", or "NONE" depending on what responded | `get_events()` | `GET /get/event_log` | *(not in MQTT mapping)* | | `get_device_info()` | `GET /get/robot_id` | *(not in MQTT mapping)* | | `get_wifi_status()` | `GET /get/wifi_status` | *(not in MQTT mapping)* | +| `find_robot()` | *(not in REST mapping)* | `find_robot` (command) | +| `request_map()` | *(not in REST mapping)* | `request_map` (command; the map arrives through monitoring) | +| `set_suction(level)` | *(not in REST mapping)* | `set_suction_eco` / `_normal` / `_max` (command) | +| `set_recharge_resume(enabled)` | *(not in REST mapping)* | `recharge_resume_on` / `_off` (command) | +| `set_evac_resume(enabled)` | *(not in REST mapping)* | `evac_resume_on` / `_off` (command) | +| `clean_rooms(names, deep=False, vacuum_map=None)` | *(not in REST mapping)* | runtime-built payload, then `start_cleaning` | +| `clean_spot(x, y, vacuum_map=None)` | *(not in REST mapping)* | runtime-built payload, then `start_cleaning` | +| `pause()` | *(not in REST mapping)* | `pause` (command; `start_cleaning` resumes) | +| `edge_clean()` | *(not in REST mapping)* | `edge_clean` (command) | +| `set_toggle(name, enabled)` | *(not in REST mapping)* | runtime-built settings payload (`CONFIG_TOGGLES`) | +| `set_carpet_detect(mode)`, `set_volume(n)` | *(not in REST mapping)* | runtime-built settings payload | ### Return Types @@ -125,6 +136,64 @@ async with VacuumClient("192.168.1.100", mqtt_mappings="sharkiq_v1") as vacuum: await vacuum.stop_monitoring() ``` +While monitoring, the client keeps the most recent status in `vacuum.last_status` and the most recent **persisted** map in `vacuum.last_map` (see below). Live map frames update `last_status.map` but never replace `last_map`, so the room definition stays available through a job. + +--- + +## Maps, Rooms and Settings + +These are MQTT-only and, today, specific to the `sharkiq_v1` mapping. Models that publish map frames deliver them through monitoring: every `VacuumStatus` that carries map data has `status.map` set to a `VacuumMap`. + +```python +def on_status(status: VacuumStatus) -> None: + if status.map is None: + return + robot = status.map.robot # MapPose(x, y, heading) or None + print(len(status.map.path), "path points, robot at", robot) + if status.map.persisted: # the end-of-job frame + print([room.name for room in status.map.rooms]) + print([e.code for e in status.map.log if e.key == "DT_WARNING_CODE"]) + +vacuum.on_status_update(on_status) +await vacuum.start_monitoring() +``` + +### Settings and locate + +```python +await vacuum.find_robot() # play the locate sound +await vacuum.request_map() # re-send the saved map (last job, no event log) +await vacuum.set_suction(SuctionLevel.MAX) # "eco" | "normal" | "max" +await vacuum.set_recharge_resume(True) +await vacuum.set_evac_resume(False) +``` + +Recharge & Resume and Evac & Resume are read back from `VacuumStatus.recharge_resume` / `evac_resume`. The suction level is **not** reported in status — the robot echoes a change once and is then silent about it — so keep the last value you set if you need to display it. + +### More settings, pause and live faults + +The SharkIQ settings block (`PbConfig` in the app's schema) is written one field at a time with `set_config(field, value)`; `CONFIG_TOGGLES` names the on/off settings (`do_not_disturb`, `child_lock`, `silent_mode`, `clean_edge`, `carpet_boost`, `button_sounds`, `underglow_lights`, `continuous_cross_hatch`, `room_by_room`, plus the two resume settings, whose writes match the app's captured commands byte for byte). Which settings a given model honours is not known in advance; the robot only echoes a setting once, so keep what you set. + +`pause()` sends `USR_CTR_PAUSE`; `start_cleaning()` (`USR_CTR_RESUME`) resumes. Status frames report the faults and warnings active now in `VacuumStatus.errors` / `warnings`, named by `sharklocal.codes`. + +### Which features a model has + +`sharklocal.compat.RobotProfile(model)` answers what the SharkClean app would show for a robot, from the cloud model string (`oem_model`, e.g. `RV3000-001D5F7F`): its family and classification, and features such as `has_auto_empty`, `do_not_disturb`, `has_volume`, `has_pin_drop`, `has_ultra_clean`, `has_underglow_lights` or `has_carpet_boost`. It is a port of the app's own rules and model table (SharkClean 6.27.0). The model is not reported over local MQTT, so it has to be supplied; a string the table lacks (retail SKUs such as `RV2610BFCA` are not cloud model strings) gives `None` for family-based features rather than a guess. + +For configuration, every model falls into one of seven robot types (`compat.ROBOT_TYPES`: `lidar`, `lidar_carpet`, `rv3000`, `spot_lidar`, `map`, `air`, `basic`), and `Capabilities(robot_type, self_empty_dock, clean_edge)` answers the same features as plain booleans; the two hardware extras vary within a type, so they are asked rather than derived. Across all 611 models in the table, a model's type plus its two extras gives exactly the per-model answers (`capabilities_for_model` does the lookup for a known model string). + +### Room, Matrix and spot cleaning + +```python +# Needs a persisted map for the room definition: either the one the client +# cached while monitoring (vacuum.last_map) or one you pass in. +await vacuum.clean_rooms(["Kitchen", "Hallway"]) +await vacuum.clean_rooms(["Kitchen"], deep=True) # Matrix Clean (two passes) +await vacuum.clean_spot(1.2, -0.4) # ~1.5 m square around (x, y) metres +``` + +Each of these publishes the map's room definition with the selection, then `start_cleaning`. Room names must match `VacuumMap.rooms` exactly (`ValueError` otherwise); with no persisted map available a `SharklocalError` is raised. Because the room definition is re-uploaded in full, **always use the latest persisted map** — a stale one renames rooms back to the names it was captured with. + --- ## Transport Introspection diff --git a/pyproject.toml b/pyproject.toml index c8d8ccf..b6df91e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "sharklocal" -version = "0.2.0" +version = "0.3.0.dev14" description = "Local control library for Shark robot vacuums, for use with Home Assistant" readme = "README.md" license = { text = "MIT" } diff --git a/sharklocal/__init__.py b/sharklocal/__init__.py index e8e6a52..ca2963b 100644 --- a/sharklocal/__init__.py +++ b/sharklocal/__init__.py @@ -41,7 +41,21 @@ load_mqtt_mapping, load_rest_mapping, ) -from .models import DeviceInfo, ProbeResult, VacuumEvent, VacuumMode, VacuumStatus +from .models import ( + DeviceInfo, + MapFeature, + MapGrid, + MapPoint, + MapPose, + MapRoom, + ProbeResult, + SuctionLevel, + VacuumEvent, + VacuumLogEntry, + VacuumMap, + VacuumMode, + VacuumStatus, +) from .mqtt_client import MQTTVacuumClient, register_decoder from .rest_client import RESTVacuumClient @@ -69,6 +83,15 @@ "VacuumEvent", "DeviceInfo", "ProbeResult", + "SuctionLevel", + # Map models + "VacuumMap", + "MapGrid", + "MapPoint", + "MapPose", + "MapRoom", + "MapFeature", + "VacuumLogEntry", # Exceptions "SharklocalError", "ConnectError", diff --git a/sharklocal/__main__.py b/sharklocal/__main__.py index 9f7dc3b..825c291 100644 --- a/sharklocal/__main__.py +++ b/sharklocal/__main__.py @@ -19,7 +19,12 @@ ) # Actions metadata for help and validation -VALID_COMMANDS = ["start", "stop", "dock", "status", "events", "info"] +VALID_COMMANDS = [ + "start", "stop", "dock", "status", "events", "info", "find", + "suction-eco", "suction-normal", "suction-max", + "recharge-resume-on", "recharge-resume-off", + "evac-resume-on", "evac-resume-off", +] ACTION_MAP = { "status": "get_status", "start": "start_cleaning", @@ -27,6 +32,14 @@ "dock": "go_home", "events": "get_events", "info": "get_robot_id", + "find": "find_robot", + "suction-eco": "set_suction_eco", + "suction-normal": "set_suction_normal", + "suction-max": "set_suction_max", + "recharge-resume-on": "recharge_resume_on", + "recharge-resume-off": "recharge_resume_off", + "evac-resume-on": "evac_resume_on", + "evac-resume-off": "evac_resume_off", } def print_status(status: VacuumStatus, prefix: str = "[STATUS]"): @@ -35,6 +48,21 @@ def print_status(status: VacuumStatus, prefix: str = "[STATUS]"): chg = f" (Charging)" if status.charging else "" mode_str = status.mode.value if hasattr(status.mode, "value") else str(status.mode) print(f"\r{prefix} Mode: {mode_str:20} | Battery: {bat}{chg}", end="", flush=True) + if status.map is not None: + print_map(status.map) + +def print_map(vacuum_map) -> None: + """Helper to summarise a map frame on its own line.""" + grid = vacuum_map.grid + robot = vacuum_map.robot + pose = f"({robot.x:.2f}, {robot.y:.2f}) @ {robot.heading:.2f} rad" if robot else "unknown" + kind = "persisted map" if vacuum_map.persisted else "live map" + rooms = ", ".join(r.name for r in vacuum_map.rooms) or "none" + print( + f"\n[MAP] {kind}: {grid.width}x{grid.height} @ {grid.resolution:.2f} m | " + f"path pts: {len(vacuum_map.path)} | robot: {pose} | rooms: {rooms}", + flush=True, + ) async def run_command(host: str, cmd: str, transport: str): """Execute a single specific command.""" @@ -328,6 +356,12 @@ def save_report(results: Dict[str, Any], save_report_arg: Any): print(f"\nReport saved to: {os.path.abspath(filename)}") def main(): + # aiomqtt requires the selector event loop on Windows. Python otherwise + # defaults to the proactor loop there, which fails before an MQTT probe can + # connect. + if sys.platform == "win32": + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + parser = setup_argparse() args = parser.parse_args() diff --git a/sharklocal/client.py b/sharklocal/client.py index 20c3aa9..d257710 100644 --- a/sharklocal/client.py +++ b/sharklocal/client.py @@ -3,14 +3,44 @@ from __future__ import annotations import asyncio +import inspect from pathlib import Path -from typing import Any, Callable, List, Optional, Union +from typing import Any, Callable, Dict, List, Optional, Union +from . import protobuf from .exceptions import ActionNotSupportedError, ConnectError, SharklocalError from .mappings import load_mqtt_mapping, load_rest_mapping -from .models import DeviceInfo, ProbeResult, VacuumEvent, VacuumStatus +from .models import ( + DeviceInfo, + ProbeResult, + SuctionLevel, + VacuumEvent, + VacuumMap, + VacuumStatus, +) from .mqtt_client import MQTTVacuumClient from .rest_client import RESTVacuumClient +from .vacuum_map import encode_room_selection, encode_spot_selection + + +# On/off settings in the SharkIQ settings block (PbConfig), by field number, +# from the app's protobuf schema. Written as PbToggleT: 1 on, 2 off. Field 8 +# (Recharge & Resume) and 7 (Evac & Resume) match the app captures exactly. +CONFIG_TOGGLES: Dict[str, int] = { + "evac_resume": 7, + "recharge_resume": 8, + "room_by_room": 12, + "continuous_cross_hatch": 13, + "clean_edge": 14, + "do_not_disturb": 18, + "carpet_boost": 19, + "child_lock": 24, + "silent_mode": 25, + "underglow_lights": 26, + "button_sounds": 27, +} +CONFIG_VOLUME = 2 +CONFIG_CARPET_DETECT = 15 class VacuumClient: @@ -73,6 +103,13 @@ def __init__( self._monitor_stop: Optional[asyncio.Event] = None self._monitor_task: Optional[asyncio.Task] = None + # Most recent status and map seen while monitoring. ``last_map`` keeps + # the latest *persisted* map (rooms, dock, vectors) — room and spot + # cleaning need its room definition — and is not replaced by the + # room-less live frames a job produces. + self.last_status: Optional[VacuumStatus] = None + self.last_map: Optional[VacuumMap] = None + # Primary transport in use. "REST" when REST is pinned and reachable, # "MQTT" when only MQTT is available, "NONE" until probe() confirms a # working transport (or a single mapping is auto-pinned). @@ -137,6 +174,16 @@ async def explore(self) -> bool: """Begin a mapping/exploration run.""" return await self._execute("explore") + async def request_map(self) -> bool: + """Ask the robot to publish its persisted map (MQTT only). + + The reply arrives through monitoring like any other map frame, and + carries the last job's path and summary but no event log — a way to + recover a job whose end-of-job frame was missed. Sent while docked; not + tried mid-job. + """ + return await self._execute("request_map") + async def get_status(self) -> VacuumStatus: """Return the current vacuum status.""" return await self._execute("get_status") @@ -153,6 +200,120 @@ async def get_wifi_status(self) -> DeviceInfo: """Return Wi-Fi connection details including MAC address.""" return await self._execute("get_wifi_status") + async def pause(self) -> bool: + """Pause the current job (resume it with :meth:`start_cleaning`).""" + return await self._execute("pause") + + async def edge_clean(self) -> bool: + """Clean along the walls.""" + return await self._execute("edge_clean") + + async def set_config(self, field_num: int, value: int) -> bool: + """Write one field of the robot's settings block (``PbConfig``). + + MQTT-only and SharkIQ-specific: the command is field 7 carrying the one + setting. :data:`CONFIG_TOGGLES` names the on/off settings; suction and + the resume settings have their own methods. + """ + payload = protobuf.encode_bytes_field(7, protobuf.encode_varint_field(field_num, value)) + return await self._send(payload) + + async def set_toggle(self, name: str, enabled: bool) -> bool: + """Switch a named on/off setting (see :data:`CONFIG_TOGGLES`).""" + if name not in CONFIG_TOGGLES: + raise ValueError(f"Unknown setting {name!r}; known: {sorted(CONFIG_TOGGLES)}") + return await self.set_config(CONFIG_TOGGLES[name], 1 if enabled else 2) + + async def set_carpet_detect(self, mode: int) -> bool: + """Set carpet detection (1 disabled, 2 automatic; codes.CARPET_DETECT_MODES).""" + return await self.set_config(CONFIG_CARPET_DETECT, mode) + + async def set_volume(self, volume: int) -> bool: + """Set the robot's voice volume.""" + return await self.set_config(CONFIG_VOLUME, volume) + + async def find_robot(self) -> bool: + """Make the vacuum play its locate sound.""" + return await self._execute("find_robot") + + async def set_suction(self, level: SuctionLevel) -> bool: + """Set the suction power level (``eco``, ``normal`` or ``max``). + + The setting has no field in the status message — the robot only echoes + it once on change — so callers wanting to display it should remember + the last level they set. + """ + return await self._execute(f"set_suction_{SuctionLevel(level).value}") + + async def set_recharge_resume(self, enabled: bool) -> bool: + """Enable or disable Recharge & Resume (finish the job after charging).""" + return await self._execute(f"recharge_resume_{'on' if enabled else 'off'}") + + async def set_evac_resume(self, enabled: bool) -> bool: + """Enable or disable Evac & Resume (empty the bin mid-job, then continue).""" + return await self._execute(f"evac_resume_{'on' if enabled else 'off'}") + + async def clean_rooms( + self, + room_names: List[str], + *, + deep: bool = False, + vacuum_map: Optional[VacuumMap] = None, + ) -> bool: + """Clean the named rooms, then start. + + Room cleaning is an MQTT-only, two-message sequence: the map's room + definition with the selection, then ``start_cleaning``. It needs a + persisted map for the room definition — pass one, or let the client use + the latest seen while monitoring (:attr:`last_map`). + + Args: + room_names: Room names exactly as shown in the app. + deep: Request a Matrix (two-pass) clean of those rooms. + vacuum_map: The persisted map to take the room definition from. + + Raises: + SharklocalError: If no persisted map is available. + ValueError: If a room name is not on the map. + ActionNotSupportedError: If no MQTT mapping is configured. + """ + payload = self._room_definition_payload( + vacuum_map, lambda m: encode_room_selection(m, room_names, deep=deep) + ) + await self._send(payload) + return await self.start_cleaning() + + async def clean_spot( + self, + x: float, + y: float, + *, + vacuum_map: Optional[VacuumMap] = None, + ) -> bool: + """Spot-clean a ~1.5 m square centred on ``(x, y)`` metres, then start. + + Same requirements as :meth:`clean_rooms`. The coordinates are in the + map frame — the one :class:`~sharklocal.models.VacuumMap` reports. + """ + payload = self._room_definition_payload( + vacuum_map, lambda m: encode_spot_selection(m, x, y) + ) + await self._send(payload) + return await self.start_cleaning() + + def _room_definition_payload( + self, + vacuum_map: Optional[VacuumMap], + build: Callable[[VacuumMap], bytes], + ) -> bytes: + chosen = vacuum_map or self.last_map + if chosen is None or not chosen.persisted: + raise SharklocalError( + "A persisted map is required for room or spot cleaning; the robot " + "publishes one each time it docks — monitor until last_map is set" + ) + return build(chosen) + # ------------------------------------------------------------------ # Mapping probe # ------------------------------------------------------------------ @@ -253,7 +414,32 @@ async def start_monitoring(self) -> None: self._monitor_stop = asyncio.Event() self._monitor_task = asyncio.ensure_future( - self._mqtt.monitor(self._status_callback, stop_event=self._monitor_stop) + self._mqtt.monitor(self._on_monitor_status, stop_event=self._monitor_stop) + ) + + async def _on_monitor_status(self, status: VacuumStatus) -> None: + """Cache the latest status and persisted map, then forward to the callback.""" + self.last_status = status + if status.map is not None and status.map.persisted and not self._same_job_poorer(status.map): + self.last_map = status.map + callback = self._status_callback + if inspect.iscoroutinefunction(callback): + await callback(status) + else: + callback(status) # type: ignore[misc] + + def _same_job_poorer(self, vacuum_map: VacuumMap) -> bool: + """``True`` if *vacuum_map* would replace a report of the same job. + + A requested map repeats the last job without its event log, so it only + supersedes the cached map when it records a different job. + """ + current = self.last_map + return ( + not vacuum_map.report + and current is not None + and current.report + and current.job_started == vacuum_map.job_started ) async def stop_monitoring(self) -> None: @@ -313,6 +499,28 @@ def active_mqtt_mapping(self) -> Optional[str]: # Internal transport evaluation # ------------------------------------------------------------------ + async def _send(self, payload: bytes) -> bool: + """Publish a runtime-built payload over the active MQTT transport. + + Only MQTT can carry these, so REST is never consulted. With several + MQTT candidates and no pinned client, each is tried in order. + """ + mqtt_options: List[MQTTVacuumClient] = ( + [self._mqtt] if self._mqtt is not None else self._mqtt_candidates + ) + if not mqtt_options: + raise ActionNotSupportedError( + "Room and spot cleaning need an MQTT mapping; none is configured" + ) + + last_connect_error: Optional[ConnectError] = None + for client in mqtt_options: + try: + return await client.send(payload) + except ConnectError as exc: + last_connect_error = exc + raise last_connect_error # type: ignore[misc] + async def _execute(self, action: str) -> Any: """Execute *action* using the best available transport. diff --git a/sharklocal/codes.py b/sharklocal/codes.py new file mode 100644 index 0000000..6c01233 --- /dev/null +++ b/sharklocal/codes.py @@ -0,0 +1,397 @@ +"""Names for the numeric codes in SharkIQ protobuf messages. + +These are the robot's own enum names (``SysStateT``, ``ErrorCodeT``, +``WarningCodeT`` and the dock-event codes), as the SharkClean app's protobuf +schema defines them. The robot's event log writes the same names as strings +(``WARN_MM_LOWLIGHT``, ``DE_USR_CTR_DOCK``); status frames carry the numbers. +Names only: the robot and the app define no descriptions for them. +""" + +from __future__ import annotations + +from typing import Dict, Iterable, List + +# Status field 4. +SYSTEM_STATES: Dict[int, str] = { + 0: "SYS_ST_NONE", + 1: "SYS_ST_UNINIT", + 2: "SYS_ST_SLEEPING", + 3: "SYS_ST_WAITING", + 4: "SYS_ST_PAUSE", + 5: "SYS_ST_ERROR", + 6: "SYS_ST_CLEANING", + 7: "SYS_ST_DOCKING", + 8: "SYS_ST_SPOTING", + 9: "SYS_ST_ALONG_WALL", + 10: "SYS_ST_REMOTE", + 11: "SYS_ST_UPDATING", + 12: "SYS_ST_WIFI_CONFIG", + 13: "SYS_ST_CHARGING", + 14: "SYS_ST_BATTERY_FULL", + 15: "SYS_ST_GO_TARGET", + 16: "SYS_ST_CLEAN_ZONE", + 17: "SYS_ST_REBOOT", + 18: "SYS_ST_POWEROFF", + 19: "SYS_ST_WIFI_CONNECTED", + 20: "SYS_ST_TEST", + 21: "SYS_ST_FACTORY_TEST", + 22: "SYS_ST_WAITING_2R_PENDING", + 23: "SYS_ST_WAITING_2R", + 24: "SYS_ST_AUTO_EXPLORE", + 25: "SYS_ST_REDOCKING", + 26: "SYS_ST_EXPLORE_DOCKING", + 27: "SYS_ST_PRIMING", + 28: "SYS_ST_RELOCAL", + 29: "SYS_ST_BASE_DOCK", + 30: "SYS_ST_MOP_CLEAN", + 31: "SYS_ST_CARPET_EXPLORE", + 32: "SYS_ST_MOP_WASH", + 33: "SYS_ST_FACTORY_RESETTING", + 34: "MAX_SYS_ST_NUM", +} + + +# Status field 5 (repeated): errors active now. +ERROR_CODES: Dict[int, str] = { + 0: "ERROR_NONE", + 1: "ERROR_INIT_WIFI", + 2: "ERROR_INIT_IMU", + 3: "ERROR_INIT_CAM", + 4: "ERROR_INIT_RVC", + 5: "ERROR_INIT_OPTIC", + 6: "ERROR_ENDATA", + 7: "ERROR_DATA_HALL", + 8: "ERROR_DATA_IR", + 9: "ERROR_DATA_CLIFF", + 10: "ERROR_DATA_BUMPER", + 11: "ERROR_DATA_IMU", + 12: "ERROR_DATA_CAM", + 13: "ERROR_DATA_TOF", + 14: "ERROR_DATA_RVC", + 16: "ERROR_WHEEL_DROP_L", + 17: "ERROR_WHEEL_DROP_R", + 18: "ERROR_WHEEL_DROP_BOTH", + 19: "ERROR_WHEEL_STUCK_L", + 20: "ERROR_WHEEL_STUCK_R", + 21: "ERROR_WHEEL_STUCK_BOTH", + 22: "ERROR_FAN_STUCK", + 23: "ERROR_FAN_BROCKEN", + 24: "ERROR_SFRONT_WHEEL_STUCK_L", + 25: "ERROR_SFRONT_WHEEL_STUCK_R", + 26: "ERROR_SFRONT_WHEEL_STUCK_BOTH", + 27: "ERROR_RFRONT_WHEEL_STUCK", + 28: "ERROR_VIBRATOR_MOTOR_STUCK", + 29: "ERROR_PUMP_STUCK", + 30: "ERROR_SFRONT_WHEEL_BROCKEN", + 31: "ERROR_RFRONT_WHEEL_BROCKEN", + 32: "ERROR_BUTTON_BROCKEN", + 33: "ERROR_PUMP_BROCKEN", + 40: "ERROR_BATTERY_ABNORMAL", + 41: "ERROR_BATTERY_CRITICAL_LOW", + 42: "ERROR_BATTERY_LOW_TO_START", + 43: "ERROR_CHARGE_VOL_ABNORMAL", + 44: "ERROR_TEMPERATURE_HIGH", + 45: "ERROR_TEMPERATURE_LOW", + 46: "ERROR_DUST_UNINSTALLED", + 47: "ERROR_TANK_UNINSTALLED", + 48: "ERROR_BASE_DOCK_FAILED", + 49: "ERROR_NO_DOCK_SIGNAL", + 50: "ERROR_ATTITUDE", + 51: "ERROR_CANNOT_FINISH_CLEAN", + 52: "ERROR_WIFI_CONFIG_TIMEOUT", + 53: "ERROR_WIFI_AUTH_FAILED", + 54: "ERROR_OTA_FAILED", + 55: "ERROR_OTA_DOWNLOAD_FAILED", + 56: "ERROR_OTA_NO_SPACE_LEFT", + 57: "ERROR_OTA_BATTERY_LOW", + 58: "ERROR_WIFI_SSID_NOT_FOUND", + 59: "ERROR_WIFI_NO_INTERNET", + 60: "ERROR_WIFI_NO_SERVICE", + 61: "ERROR_CLIFF_START_FAIL", + 62: "ERROR_WHEEL_DROP_START_FAIL", + 63: "ERROR_BUMPER_START_FAIL", + 64: "ERROR_PP_FATAL", + 65: "ERROR_PP_ESCAPE_FAILED", + 66: "ERROR_PP_CANNOT_REACH_DEST", + 67: "ERROR_SPOT_ON_DOCKER", + 68: "ERROR_AED_NOT_FOUND", + 69: "ERROR_AED_PROC_STUCK", + 70: "ERROR_ROBOT_STUCK", + 71: "ERROR_BOUNDARY", + 80: "ERROR_VT_FATAL", + 81: "ERROR_VT_SLIP", + 82: "ERROR_MAP_INCONSISTENT", + 83: "ERROR_MAP_BUSY", + 84: "ERROR_MAP_IO_ERROR", + 85: "ERROR_MAP_NO_SPACE_LEFT", + 86: "ERROR_MAP_RELOC_FAILED", + 87: "ERROR_VIBRATOR_MOTOR_BROCKEN", + 88: "ERROR_TEMPERATURE_ERR", + 89: "ERROR_GNG_ZONE_CLEAN_FAILED", + 90: "ERROR_PICK_UP", + 91: "ERROR_LOW_LIGHT", + 92: "ERROR_SOFTCALIFAILED", + 93: "ERROR_MCU_PARAM", + 94: "ERROR_DUST_UNINSTALLED_IN_REDOCK", + 95: "ERROR_BATTERY_CRITICAL_LOW_IN_PAUSE", + 96: "ERROR_LIDAR_BROCKEN", + 97: "ERROR_NOGO_ESCAPE_TIMEOUT", + 98: "ERROR_LIDAR_OVER_CURRENT", + 99: "ERROR_LIDAR_MODEL_UNKNOWN", + 100: "ERROR_LIDAR_LOST_SPEED", + 101: "ERROR_LIDAR_CRC_FAILED", + 102: "ERROR_LIDAR_DATA_TIMEOUT", + 103: "ERROR_LIDAR_COVERED", + 104: "ERROR_LIDAR_INIT_FAILED", + 105: "ERROR_WATER_TANK_EMPTY", + 106: "ERROR_EXPLORE_MODE_INSTALL_TANK", + 107: "ERROR_CARPET_DETECT", + 108: "ERROR_FANJET_STUCK", + 109: "ERROR_FANJET_BROKEN", + 110: "ERROR_CT_UNINSTALL", + 111: "ERROR_CT_OVERFLOW", + 112: "ERROR_ST_FULL", + 113: "ERROR_WT_UNINSTALL", + 114: "ERROR_WT_EMPTY", + 115: "ERROR_SP_WORK_WITHOUT_CUR", + 116: "ERROR_WSP_WORK_CUR_OVERLOAD", + 117: "ERROR_WFAN_WORK_WITHOUT_CUR", + 118: "ERROR_WFAN_WORK_CUR_OVERLOAD", + 119: "ERROR_WWP_WORK_WITHOUT_CUR", + 120: "ERROR_WWP_WORK_CUR_OVERLOAD", + 121: "ERROR_WFAN_IDLE_WITH_CUR", + 122: "ERROR_WWP_IDLE_WITH_CUR", + 123: "ERROR_WSP_IDLE_WITH_CUR", + 124: "ERROR_WCHARGING_CUR", + 125: "ERROR_WCHARGE_INTRRUPT", + 126: "ERROR_WCHARGE_OVER_VOLTAGE", + 127: "ERROR_WCHARGE_LOW_VOLTAGE", + 128: "ERROR_WS_DUST_UNINSTALL", + 129: "ERROR_WS_ROBOT_DISCONNECT", + 130: "ERROR_WS_ROBOT_DOCK_DISCONNECT", + 131: "ERROR_SPLIT_ZONE_FAIL", + 132: "ERROR_MERGE_ZONE_FAIL", + 133: "ERROR_RESET_ZONE_FAIL", + 134: "ERROR_SPLIT_ZONE_MULTIPLE_REGIONS", + 135: "ERROR_SPLIT_ZONE_AREA_SMALL", + 136: "ERROR_BATTERY_OVER_CURRENT", + 137: "ERROR_BATTERY_TIMEOUT", + 138: "ERROR_BATTERY_OVER_TEMP", + 139: "ERROR_BATTERY_LOW_TEMP", + 140: "ERROR_WASH_MOP_TIMEOUT", + 141: "ERROR_DRY_TIMEOUT", + 142: "ERROR_DRY_INTERRUPT", + 143: "ERROR_DRY_DOCK_MODE_UNMATCH", + 144: "ERROR_CARPET_START_FAILED", + 145: "ERROR_CARPET_ESCAPE_TIMEOUT", + 146: "ERROR_RESTORE_FACTORY_FAILED", + 147: "ERROR_CLEANSENSE_DIRT", + 148: "ERROR_SERVO_OVER_CURRENT", + 149: "ERROR_WET_CLEAN_DETACH_PAD", + 150: "ERROR_DRY_CLEAN_ATTACH_PAD", + 151: "ERROR_MFD_CLEAN_TANK_UNINSTALL", + 152: "ERROR_MFD_CLEAN_TANK_EMPTY", + 153: "ERROR_MFD_GREY_TANK_UNINSTALL", + 154: "ERROR_MFD_GREY_TANK_FULL", + 155: "ERROR_MFD_SHUTTLE_OVER_CURRENT", + 156: "ERROR_MFD_PUMP_OVER_CURRENT", + 157: "ERROR_MFD_PRESSURE_OVER_CURRENT", + 158: "ERROR_MFD_GREY_OVER_CURRENT", + 159: "ERROR_MFD_DRY_FAN_OVER_CURRENT", + 160: "ERROR_MFD_WATER_OVER_FLOW", + 161: "ERROR_MFD_CHARGE_OVER_CURRENT", + 162: "ERROR_UFD_MODEL_UNKNOWN", + 163: "ERROR_EXPLORE_PAD_ATTACHED", + 164: "ERROR_MFD_SHUTTLE_BROKEN", + 165: "ERROR_MFD_PUMP_BROKEN", + 166: "ERROR_MFD_DETACH_MOTOR_BROKEN", + 167: "ERROR_MFD_GREY_BROKEN", + 168: "ERROR_MFD_DRY_FAN_BROKEN", + 169: "ERROR_MFD_DETACH_MOTOR_OVER_CURRENT", + 170: "ERROR_DEEP_CLEAN_OFF_DOCK", + 171: "ERROR_UFD_INIT_FAILED", + 172: "ERROR_UFD_DATA_TIMEOUT", + 173: "ERROR_SERVO_BROKEN", + 174: "ERROR_WATER_TANK_REFILL_EMPTY", + 175: "ERROR_AGITATOR_RESET_FAILED", + 176: "ERROR_LINE_LASER_INIT_FAILED", + 177: "ERROR_LINE_LASER_DATA_TIMEOUT", + 178: "ERROR_LINE_LASER_MODEL_UNKNOWN", + 179: "ERROR_OBS_AVOID_INIT_FAILED", + 180: "ERROR_OBS_AVOID_DATA_TIMEOUT", + 181: "ERROR_WALL_FOLLOW_INIT_FAILED", + 182: "ERROR_WALL_FOLLOW_DATA_TIMEOUT", + 183: "ERROR_MFD_BOILER_NTC_ABNORMAL", + 184: "ERROR_MFD_HEATER_NTC_ABNORMAL", + 185: "ERROR_MFD_BOILER_ABNORMAL", + 186: "ERROR_MFD_HEATER_ABNORMAL", + 187: "ERROR_MFD_LIMIT_SWITCH_BROKEN", + 188: "ERROR_MFD_VALVE_OVER_CURRENT", + 189: "ERROR_MFD_VALVE_BROKEN", + 190: "ERROR_MFD_SCALING_NTC_ABNORMAL", + 191: "MAX_ERROR_NUM", +} + + +# Status field 6 (repeated): warnings active now; also DT_WARNING_CODE in the log. +WARNING_CODES: Dict[int, str] = { + 0: "WARN_NONE", + 1: "WARN_BATTERY_LOW", + 2: "WARN_MCU_PARAM", + 3: "WARN_TANK_EMPTY", + 4: "WARN_LOW_LIGHT", + 5: "WARN_NO_LIGHT", + 6: "WARN_UNLOOPCLOSE", + 7: "WARN_WHEEL_FLY", + 8: "WARN_WHEEL_SLIP", + 9: "WARN_INCLINE", + 10: "WARN_DANGEROUS_ZONE", + 11: "WARN_VT_LOST_LOCALIZATION", + 12: "WARN_VT_RELOC_FAILED", + 13: "WARN_LENS_DIRTY", + 14: "WARN_PP_NO_DOCK", + 15: "WARN_TANK_LOW", + 16: "WARN_WIFI_CONFIG_TIMEOUT", + 17: "WARN_WIFI_AUTH_FAILED", + 18: "WARN_WIFI_SSID_NOT_FOUND", + 19: "WARN_WIFI_NO_INTERNET", + 20: "WARN_FIND_ME", + 21: "WARN_CAMERA_RUN", + 22: "WARN_RECHARGE_RESUME_OPEN", + 23: "WARN_RECHARGE_RESUME_CLOSE", + 24: "WARN_WHEEL_OVER_CURRENT", + 25: "WARN_EVAUCATION_RESUME_OPEN", + 26: "WARN_EVAUCATION_RESUME_CLOSE", + 27: "WARN_SAVE_MAP_BUSY", + 28: "WARN_ESCAPE_FAILED", + 29: "WARN_PICK_UP", + 30: "WARN_OVER_CURRENT", + 31: "WARN_MM_ALLRIGHT", + 32: "WARN_MM_FIRSTCLEAN", + 33: "WARN_MM_TRAINING", + 34: "WARN_MM_NOTTRAINING", + 35: "WARN_MM_AREASMALL", + 36: "WARN_MM_RESETFLOOR1", + 37: "WARN_MM_RESETFLOOR2", + 38: "WARN_MM_SIMILARCHECK1", + 39: "WARN_MM_SIMILARCHECK2", + 40: "WARN_MM_SIMILARCHECK3", + 41: "WARN_MM_REPLACESUCC", + 42: "WARN_MM_NOTFROMSTATION", + 43: "WARN_MM_LOWLIGHT", + 44: "WARN_MM_NOTFINISH", + 45: "WARN_MM_NOTEFFIENCY", + 46: "WARN_MCU_CALI_RESETTED", + 47: "WARN_MCU_CALI_STOP_OK", + 48: "WARN_MCU_CALI_STOP_EARLY", + 49: "WARN_NEED_ENABLE_RR", + 50: "WARN_DUST_FULL", + 51: "WARN_RBR_NOT_COVER_ALL", + 52: "WARN_RELOC_FAILED_WITH_NOGO", + 53: "WARN_BAD_RUN", + 54: "WARN_MAP_SYNC_FAILED", + 55: "WARN_ALL_FLOOR_LOCKED", + 56: "WARN_LIDAR_MAP_INCONSISTENT", + 57: "WARNING_CHARGING_INTERRUPTED", + 58: "WARN_LIDAR_BROKEN", + 59: "WARN_CT_UNINSTALL", + 60: "WARN_CT_OVERFLOW", + 61: "WARN_ST_FULL", + 62: "WARN_WT_UNINSTALL", + 63: "WARN_WT_EMPTY", + 64: "WARN_LACK_OF_WATER", + 65: "WARN_CANT_EDIT_MAP", + 66: "WARN_CANT_SAVE_MAP", + 67: "WARN_CLEANSENSE_DIRT", + 68: "WARN_PARTIAL_CLEANED", + 69: "WARN_SERVO_MOTOR_BROKEN", + 70: "WARN_SERVO_MOTOR_OVER_CURRENT", + 71: "WARN_SERVO_VOLTAGE_L", + 72: "WARN_SERVO_VOLTAGE_R", + 73: "WARN_SERVO_ANGLE_L", + 74: "WARN_SERVO_ANGLE_R", + 75: "WARN_SERVO_OVERTEMP_L", + 76: "WARN_SERVO_OVERTEMP_R", + 77: "WARN_SERVO_STALL_L", + 78: "WARN_SERVO_STALL_R", + 79: "WARN_SERVO_CHECKSUM_L", + 80: "WARN_SERVO_CHECKSUM_R", + 81: "WARN_SERVO_OC_L", + 82: "WARN_SERVO_OC_R", + 83: "WARN_SERVO_PARSING_L", + 84: "WARN_SERVO_PARSING_R", + 85: "WARN_SERVO_BROKEN_L", + 86: "WARN_SERVO_BROKEN_R", + 87: "WARN_SERVO_CLEAN_OC_L", + 88: "WARN_SERVO_CLEAN_OC_R", + 89: "WARN_LEFT_TOF_DIRT", + 90: "WARN_RIGHT_TOF_DIRT", + 91: "WARN_PAD_SHIFT_TOF_DIRT", + 92: "WARN_AED_PROC_STUCK", + 93: "WARN_SERVO_NO_DATA_L", + 94: "WARN_SERVO_NO_DATA_R", + 95: "WARN_SERVO_CHECKSUM", + 96: "WARN_MM_NEW_FLOOR", + 97: "WARN_MM_UPDATE_FLOOR", + 98: "WARN_DOCK_OTA_FAILED", + 99: "WARN_MM_UPDATE_SLAM", + 100: "MAX_WARN_NUM", +} + + +# Why the robot went to its dock: DT_DOCK_CODE in the log. +DOCK_EVENTS: Dict[int, str] = { + 0: "DE_NONE", + 1: "DE_ER", + 2: "DE_2R", + 3: "DE_BAT_LOW", + 4: "DE_ESC_FAILED", + 5: "DE_RELOC_FAILED", + 6: "DE_REDOCK", + 7: "DE_USR_CTR_DOCK", + 8: "DE_CLEAN_FINISH", + 9: "DE_FR", + 10: "DE_BAT_LOW_DC", + 11: "DE_CLEAN_FINISH_DC", +} + + +# Device info field 1. +WIFI_STATES: Dict[int, str] = { + 0: "WIFI_NONE", + 1: "WIFI_CONFIGURING", + 2: "WIFI_CONNECTING", + 3: "WIFI_CONNECTED", + 4: "WIFI_CONNECTED_INTERNET", + 5: "WIFI_DRIVER_ERR", + 6: "WIFI_UNKNOW_ERR", + 7: "WIFI_UNCONNECTED", + 8: "WIFI_CONFIG_TIMEOUT", + 9: "WIFI_SSID_NOT_FOUND", + 10: "WIFI_AUTH_FAILED", + 11: "WIFI_NO_SERVICE", + 12: "WIFI_NO_INTERNET", +} + + +# Status field 44 and config field 15. +CARPET_DETECT_MODES: Dict[int, str] = { + 0: "CD_NONE", + 1: "CD_DISABLE_ALL", + 2: "CD_AUTO", +} + + +# Status field 41. +RELOCATION_STATES: Dict[int, str] = { + 0: "RS_NONE", + 1: "RS_RELOC", + 2: "RS_FAIL", + 3: "RS_SUCCESS", + 4: "RS_UNRELOC", +} + + +def names(table: Dict[int, str], codes: Iterable[int]) -> List[str]: + """Names for *codes*, keeping unknown numbers visible as ``UNKNOWN_``.""" + return [table.get(code, f"UNKNOWN_{code}") for code in codes] diff --git a/sharklocal/compat.py b/sharklocal/compat.py new file mode 100644 index 0000000..c416047 --- /dev/null +++ b/sharklocal/compat.py @@ -0,0 +1,1016 @@ +"""Which features a Shark robot has, by its model string, as the SharkClean app decides. + +A port of the app's own capability logic (its embedded "launch" module, SharkClean +6.27.0). Almost everything follows from one string, the robot's cloud model +(``oem_model``, e.g. ``RV2500AWSX``): a table gives its family, the family its +classification, letters in the model prefix and a hex bitmask add hardware, and a +few exact model lists pick out product lines. + +The model is not reported over local MQTT, so callers supply it. Features are +three-valued: ``True`` / ``False`` as the app would decide, or ``None`` when the +model is missing from the table (a retail SKU such as ``RV2610BFCA`` is not the +cloud model string) and a family-based answer cannot be given. +""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Dict, FrozenSet, Optional + +# Fs.robots: cloud model string -> family. +MODEL_FAMILIES: Dict[str, str] = { + "AV752": "RandomBounceAV75", + "AV753": "RandomBounceAV75", + "AV911": "Mesa3", + "AV911S": "Mesa3", + "AV970": "Valley1", + "AV990": "Valley2", + "AV992": "Mesa3", + "AV993": "Mesa3", + "RV1000": "Valley1", + "RV1000A": "Mesa1", + "RV1000A-CN": "Mesa1", + "RV1000ADev-CN": "RandomBounceOther", + "RV1000A-EU": "Mesa1", + "RV1000A-JP": "Mesa1", + "RV1000A-UK": "Mesa1", + "RV1000-CN": "Valley1", + "RV1000Dev-CN": "RandomBounceOther", + "RV1000-EU": "Valley1", + "RV1000-JP": "Valley1", + "RV1000-UK": "Valley1", + "RV100V2": "Valley2", + "RV100V3": "Valley2", + "RV1100": "Valley2", + "RV1100A": "Mesa2", + "RV1100A2": "Mesa2", + "RV1100A3": "Mesa2", + "RV1100AA": "MesaAir", + "RV1100AA-CN": "MesaAir", + "RV1100AA-EU": "MesaAir", + "RV1100AA-JP": "MesaAir", + "RV1100AA-UK": "MesaAir", + "RV1100AAX": "MesaAir", + "RV1100AAXDev": "MesaAir", + "RV1100AB": "Mesa2", + "RV1100AC": "Mesa2", + "RV1100A-CN": "Mesa2", + "RV1100A-EU": "Mesa2", + "RV1100A-JP": "Mesa2", + "RV1100A-UK": "Mesa2", + "RV1100AX": "Mesa2", + "RV1100AXDev": "Mesa2", + "RV1100-CN": "Valley2", + "RV1100-EU": "Valley2", + "RV1100-JP": "Valley2", + "RV1100-UK": "Valley2", + "RV1100V2": "Valley2", + "RV1100V3": "Valley2", + "RV1100VA": "ValleyAir", + "RV1100VA-CN": "ValleyAir", + "RV1100VA-EU": "ValleyAir", + "RV1100VA-JP": "ValleyAir", + "RV1100VA-UK": "ValleyAir", + "RV1100VAX": "ValleyAir", + "RV1100VAXDev": "ValleyAir", + "RV1100VB": "ValleyAir", + "RV1100VC": "ValleyAir", + "RV1100X": "Valley2", + "RV1100XDev": "Valley2", + "RV1107": "Valley2", + "RV1107A": "Mesa2", + "RV1107VA": "ValleyAir", + "RV1107AA": "MesaAir", + "RV1107X": "Valley2", + "RV1107AX": "Mesa2", + "RV1107VAX": "ValleyAir", + "RV1107AAX": "MesaAir", + "RV19GyroDev": "RandomBounceOther", + "RV19GyroPDev": "RandomBounceOther", + "RV19OPPDev": "RandomBounceOther", + "RV19PosDev": "RandomBounceOther", + "RV2000D": "Gaia", + "RV2000D-EU": "Gaia", + "RV2000D-UK": "Gaia", + "RV2000DX": "Gaia", + "RV2000DXDev": "Gaia", + "RV2000WD": "Poseidon", + "RV2000WD-EU": "Poseidon", + "RV2000WD-UK": "Poseidon", + "RV2000WX": "Poseidon", + "RV2000WXDev": "Poseidon", + "RV2018Hill": "RandomBounceOther", + "RV2018HillPlus": "RandomBounceOther", + "RV2019QF": "Valley1", + "RV2019QFA": "Mesa1", + "RV2019QFA-CN": "RandomBounceOther", + "RV2019QF-CN": "RandomBounceOther", + "RV20GaiDev": "Gaia", + "RV20PosDev": "Poseidon", + "RV20QFADev": "Mesa3", + "RV20QFDev": "Valley2", + "RV2100DF": "Gaia", + "RV2100DFDev": "Gaia", + "RV2100WF": "Poseidon", + "RV2100WFDev": "Poseidon", + "RV21QFAADev": "MesaAir", + "RV21QFADev": "Mesa3", + "RV21QFDev": "Valley3", + "RV21QFVADev": "ValleyAir", + "RV2500A": "Three60", + "RV2500A-EU": "Three60", + "RV2500A-UK": "Three60", + "RV2500AX": "Three60", + "RV2500AXDev": "Three60", + "RV360LDev": "Three60", + "RV750": "RandomBounceRV75", + "RV750G": "RandomBounceRV75", + "RV750G-EU": "RandomBounceRV75", + "RV750G-UK": "RandomBounceRV75", + "RV750L": "RandomBounceRV75", + "RV750L-CN": "RandomBounceRV75", + "RV750LDev": "RandomBounceRV75", + "RV750LDev-CN": "RandomBounceRV75", + "RV750L-EU": "RandomBounceRV75", + "RV750L-JP": "RandomBounceRV75", + "RV750L-UK": "RandomBounceRV75", + "RV750N": "RandomBounceRV75", + "RV750NDev": "RandomBounceRV75", + "RV750O": "RandomBounceRV75", + "RV750P": "RandomBounceRV75", + "RV750P-EU": "RandomBounceRV75", + "RV750P-UK": "RandomBounceRV75", + "RV750R": "RandomBounceRV75", + "RV750RDev": "RandomBounceRV75", + "RV750X": "RandomBounceRV75", + "RV750XDev": "RandomBounceRV75", + "RV754G-UK": "RandomBounceRV75", + "RV754P-UK": "RandomBounceRV75", + "RV850": "RandomBounceRV85", + "RV850Dev": "RandomBounceRV85", + "RV871": "RandomBounceRV87", + "RV871-CN": "RandomBounceRV87", + "RV871Dev": "RandomBounceRV87", + "RV871Dev-CN": "RandomBounceRV87", + "RV871-EU": "RandomBounceRV87", + "RV871-JP": "RandomBounceRV87", + "RV871P": "RandomBounceRV87", + "RV871P-CN": "RandomBounceRV87", + "RV871P-EU": "RandomBounceRV87", + "RV871P-JP": "RandomBounceRV87", + "RV871P-UK": "RandomBounceRV87", + "RV871-UK": "RandomBounceRV87", + "RV912": "MesaAir", + "RV912S": "MesaAir", + "RV912SCA": "MesaAir", + "RV913S": "MesaAir", + "RV914SCA": "MesaAir", + "RV990CA": "ValleyAir", + "RoboVac01": "RandomBounceOther", + "RV360ZDev": "Three60", + "RV2500AZ": "Three60", + "RV1300S3EU": "MesaAir", + "RV2500WD": "Three60WetDry", + "RV2500WDDev": "Three60WetDry", + "RV360LAFDev": "Three60", + "RV360LWFDev": "Three60WetDry", + "RV360LBFDev": "Three60WetDry", + "RV2500AF": "Three60", + "RV2500WF": "Three60WetDry", + "RV2500BF": "Three60WetDry", + "RV2500AF-EU": "Three60", + "RV2500AF-UK": "Three60", + "RV360LAWFXDev": "Three60WetDry", + "RV360LAWFDev": "Three60WetDry", + "RV360LAWXDev": "Three60WetDry", + "RV360LAWDev": "Three60WetDry", + "RV360LAFXDev": "Three60", + "RV360LAXDev": "Three60", + "RV360LADev": "Three60", + "RV360LWFXDev": "Three60WetDry", + "RV360LWXDev": "Three60WetDry", + "RV360LWDev": "Three60WetDry", + "RV360LFXDev": "Three60", + "RV360LFDev": "Three60", + "RV360LXDev": "Three60", + "RV2300D": "Three60", + "RV2300AE": "Three60", + "RV2300S": "Three60", + "RV2300D0-US": "Three60", + "RV2300D0-JP": "Three60", + "RV2300C0-US": "Three60", + "RV2300E0-US": "Three60", + "RV2300E0-EU": "Three60", + "RV2300E0-JP": "Three60", + "RV2500AWFX": "Three60WetDry", + "RV2500AWF": "Three60WetDry", + "RV2500AWX": "Three60WetDry", + "RV2500AW": "Three60WetDry", + "RV2500AFX": "Three60", + "RV2500WFX": "Three60WetDry", + "RV2500WX": "Three60WetDry", + "RV2500W": "Three60WetDry", + "RV2500FX": "Three60", + "RV2500F": "Three60", + "RV2500X": "Three60", + "RV2500": "Three60", + "RV2500AWFX-EU": "Three60WetDry", + "RV2500AWF-EU": "Three60WetDry", + "RV2500AWX-EU": "Three60WetDry", + "RV2500AW-EU": "Three60WetDry", + "RV2500AFX-EU": "Three60", + "RV2500AX-EU": "Three60", + "RV2500WFX-EU": "Three60WetDry", + "RV2500WF-EU": "Three60WetDry", + "RV2500WX-EU": "Three60WetDry", + "RV2500W-EU": "Three60WetDry", + "RV2500FX-EU": "Three60", + "RV2500F-EU": "Three60", + "RV2500X-EU": "Three60", + "RV2500-EU": "Three60", + "RV2500AWFX-UK": "Three60WetDry", + "RV2500AWF-UK": "Three60WetDry", + "RV2500AWX-UK": "Three60WetDry", + "RV2500AW-UK": "Three60WetDry", + "RV2500AFX-UK": "Three60", + "RV2500AX-UK": "Three60", + "RV2500WFX-UK": "Three60WetDry", + "RV2500WF-UK": "Three60WetDry", + "RV2500WX-UK": "Three60WetDry", + "RV2500W-UK": "Three60WetDry", + "RV2500FX-UK": "Three60", + "RV2500F-UK": "Three60", + "RV2500X-UK": "Three60", + "RV2500-UK": "Three60", + "RV360LVADev": "Three60", + "RV360LVAXDev": "Three60", + "RV360LAADev": "Three60", + "RV360LAAXDev": "Three60", + "RV2500VA": "Three60", + "RV2500VAX": "Three60", + "RV2500AA": "Three60", + "RV2500AAX": "Three60", + "RV2500VA-JP": "Three60", + "RV365LAWFXDev": "Three60WetDry", + "RV365LAWFDev": "Three60WetDry", + "RV365LAWXDev": "Three60WetDry", + "RV365LAWDev": "Three60WetDry", + "RV365LAFXDev": "Three60", + "RV365LAFDev": "Three60", + "RV365LAXDev": "Three60", + "RV365LADev": "Three60", + "RV365LWFXDev": "Three60WetDry", + "RV365LWFDev": "Three60WetDry", + "RV365LWXDev": "Three60WetDry", + "RV365LWDev": "Three60WetDry", + "RV365LFXDev": "Three60", + "RV365LFDev": "Three60", + "RV365LXDev": "Three60", + "RV365LDev": "Three60", + "RV2500AA-EU": "Three60", + "RV2500VA-EU": "Three60", + "RV2500VA-UK": "Three60", + "RV2500AA-UK": "Three60", + "RV2500AA-JP": "Three60", + "RV380LAWFDev": "Three60WetDry", + "RV380LAWDev": "Three60WetDry", + "RV380LWFDev": "Three60WetDry", + "RV380LWDev": "Three60WetDry", + "RV380LAWFXDev": "Three60WetDry", + "RV380LAWXDev": "Three60WetDry", + "RV380LWFXDev": "Three60WetDry", + "RV380LWXDev": "Three60WetDry", + "RV2500-JP": "Three60", + "RV2500A-JP": "Three60", + "RV2500AF-JP": "Three60", + "RV2500AW-JP": "Three60WetDry", + "RV2500AWF-JP": "Three60WetDry", + "RV2500F-JP": "Three60", + "RV2500W-JP": "Three60WetDry", + "RV2500WF-JP": "Three60WetDry", + "RV2505": "Three60", + "RV2505-JP": "Three60", + "RV2505A": "Three60", + "RV2505A-JP": "Three60", + "RV2505AF": "Three60", + "RV2505AF-JP": "Three60", + "RV2505AW": "Three60WetDry", + "RV2505AW-JP": "Three60WetDry", + "RV2505AWF": "Three60WetDry", + "RV2505AWF-JP": "Three60WetDry", + "RV2505F": "Three60", + "RV2505F-JP": "Three60", + "RV2505W": "Three60WetDry", + "RV2505W-JP": "Three60WetDry", + "RV2505WF": "Three60WetDry", + "RV2505WF-JP": "Three60WetDry", + "RV380LADev": "Three60", + "RV380LAFDev": "Three60", + "RV380LAFXDev": "Three60", + "RV380LAXDev": "Three60", + "RV380LDev": "Three60", + "RV380LFDev": "Three60", + "RV380LFXDev": "Three60", + "RV380LXDev": "Three60", + "RV360LAAPDev": "Three60", + "RV360LVAPDev": "Three60", + "RV360LAAXPDev": "Three60", + "RV360LVAXPDev": "Three60", + "RV2500AAP": "Three60", + "RV2500AAXP": "Three60", + "RV2500VAP": "Three60", + "RV2500VAXP": "Three60", + "RV2500AAP-JP": "Three60", + "RV2500VAP-JP": "Three60", + "RV2500AAP-EU": "Three60", + "RV2500VAP-EU": "Three60", + "RV2500AAP-UK": "Three60", + "RV2500VAP-UK": "Three60", + "RV2800AW": "Three60WetDry", + "RV2800AWF": "Three60WetDry", + "RV2800AWFX": "Three60WetDry", + "RV2800AWX": "Three60WetDry", + "RV2800W": "Three60WetDry", + "RV2800WF": "Three60WetDry", + "RV2800WFX": "Three60WetDry", + "RV2800WX": "Three60WetDry", + "RV2800A": "Three60", + "RV2800AF": "Three60", + "RV2800AFX": "Three60", + "RV2800AX": "Three60", + "RV2800": "Three60", + "RV2800F": "Three60", + "RV2800FX": "Three60", + "RV2800X": "Three60", + "RV2800AW-EU": "Three60WetDry", + "RV2800AWFX-EU": "Three60WetDry", + "RV2800AWX-EU": "Three60WetDry", + "RV2800W-EU": "Three60WetDry", + "RV2800WF-EU": "Three60WetDry", + "RV2800WFX-EU": "Three60WetDry", + "RV2800WX-EU": "Three60WetDry", + "RV2800A-EU": "Three60", + "RV2800AF-EU": "Three60", + "RV2800AFX-EU": "Three60", + "RV2800AX-EU": "Three60", + "RV2800-EU": "Three60", + "RV2800F-EU": "Three60", + "RV2800FX-EU": "Three60", + "RV2800X-EU": "Three60", + "RV2800AW-UK": "Three60WetDry", + "RV2800AWF-UK": "Three60WetDry", + "RV2800AWFX-UK": "Three60WetDry", + "RV2800AWX-UK": "Three60WetDry", + "RV2800W-UK": "Three60WetDry", + "RV2800WF-UK": "Three60WetDry", + "RV2800WFX-UK": "Three60WetDry", + "RV2800WX-UK": "Three60WetDry", + "RV2800A-UK": "Three60", + "RV2800AF-UK": "Three60", + "RV2800AFX-UK": "Three60", + "RV2800AX-UK": "Three60", + "RV2800-UK": "Three60", + "RV2800F-UK": "Three60", + "RV2800FX-UK": "Three60", + "RV2800X-UK": "Three60", + "RV2500AABDev": "Three60", + "RV2500AAXBDev": "Three60", + "RV2500VABDev": "Three60", + "RV2500VAXBDev": "Three60", + "RV2500AAPBDev": "Three60", + "RV2500AAXPBDev": "Three60", + "RV2500VAPBDev": "Three60", + "RV2500VAXPBDev": "Three60", + "RV2500AABDev-JP": "Three60", + "RV2500AAXBDev-JP": "Three60", + "RV2500VABDev-JP": "Three60", + "RV2500VAXBDev-JP": "Three60", + "RV2500AAPBDev-JP": "Three60", + "RV2500AAXPBDev-JP": "Three60", + "RV2500VAPBDev-JP": "Three60", + "RV2500VAXPBDev-JP": "Three60", + "RV360LAABDev": "Three60", + "RV360LAAXBDev": "Three60", + "RV360LVABDev": "Three60", + "RV360LVAXBDev": "Three60", + "RV360LAAPBDev": "Three60", + "RV360LAAXPBDev": "Three60", + "RV360LVAPBDev": "Three60", + "RV360LVAXPBDev": "Three60", + "RV2500AAB-EU": "Three60", + "RV2500AAXB-EU": "Three60", + "RV2500VAB-EU": "Three60", + "RV2500VAXB-EU": "Three60", + "RV2500AAPB-EU": "Three60", + "RV2500AAXPB-EU": "Three60", + "RV2500VAPB-EU": "Three60", + "RV2500VAXPB-EU": "Three60", + "RV2500AAB-UK": "Three60", + "RV2500AAXB-UK": "Three60", + "RV2500VAB-UK": "Three60", + "RV2500VAXB-UK": "Three60", + "RV2500AAPB-UK": "Three60", + "RV2500AAXPB-UK": "Three60", + "RV2500VAPB-UK": "Three60", + "RV2500VAXPB-UK": "Three60", + "RV2500AAB": "Three60", + "RV2500AAXB": "Three60", + "RV2500VAB": "Three60", + "RV2500VAXB": "Three60", + "RV2500AAPB": "Three60", + "RV2500AAXPB": "Three60", + "RV2500VAPB": "Three60", + "RV2500VAXPB": "Three60", + "RV2500AAB-JP": "Three60", + "RV2500AAXB-JP": "Three60", + "RV2500VAB-JP": "Three60", + "RV2500VAXB-JP": "Three60", + "RV2500AAPB-JP": "Three60", + "RV2500AAXPB-JP": "Three60", + "RV2500VAPB-JP": "Three60", + "RV2500VAXPB-JP": "Three60", + "RV2500AWFB": "Three60WetDry", + "RV2500AWFXB": "Three60WetDry", + "RV2500AWB": "Three60WetDry", + "RV2500AWXB": "Three60WetDry", + "RV2500WFB": "Three60WetDry", + "RV2500WFXB": "Three60WetDry", + "RV2500WB": "Three60WetDry", + "RV2500WXB": "Three60WetDry", + "RV2500AWFB-JP": "Three60WetDry", + "RV2500AWFXB-JP": "Three60WetDry", + "RV2500AWB-JP": "Three60WetDry", + "RV2500AWXB-JP": "Three60WetDry", + "RV2500WFB-JP": "Three60WetDry", + "RV2500WFXB-JP": "Three60WetDry", + "RV2500WB-JP": "Three60WetDry", + "RV2500WXB-JP": "Three60WetDry", + "RV360LAWFBDev": "Three60WetDry", + "RV360LAWFXBDev": "Three60WetDry", + "RV360LAWBDev": "Three60WetDry", + "RV360LAWXBDev": "Three60WetDry", + "RV360LWFBDev": "Three60WetDry", + "RV360LWFXBDev": "Three60WetDry", + "RV360LWBDev": "Three60WetDry", + "RV360LWXBDev": "Three60WetDry", + "RV2500AWFB-EU": "Three60WetDry", + "RV2500AWFXB-EU": "Three60WetDry", + "RV2500AWB-EU": "Three60WetDry", + "RV2500AWXB-EU": "Three60WetDry", + "RV2500WFB-EU": "Three60WetDry", + "RV2500WFXB-EU": "Three60WetDry", + "RV2500WB-EU": "Three60WetDry", + "RV2500WXB-EU": "Three60WetDry", + "RV2500AWFB-UK": "Three60WetDry", + "RV2500AWFXB-UK": "Three60WetDry", + "RV2500AWB-UK": "Three60WetDry", + "RV2500AWXB-UK": "Three60WetDry", + "RV2500WFB-UK": "Three60WetDry", + "RV2500WFXB-UK": "Three60WetDry", + "RV2500WB-UK": "Three60WetDry", + "RV2500WXB-UK": "Three60WetDry", + "RV381LAWFDev": "Three60", + "RV382LAWFDev": "Three60", + "RV381LAWFUSDev": "Three60WetDry", + "RV382LAWFUSDev": "Three60WetDry", + "RV2530AWFB": "Three60WetDry", + "RV2530WFB": "Three60WetDry", + "RV2530AWB": "Three60WetDry", + "RV2530WB": "Three60WetDry", + "RV2530WFB-JP": "Three60WetDry", + "RV2530AWB-JP": "Three60WetDry", + "RV2530WB-JP": "Three60WetDry", + "RV2530AWFB-EU": "Three60WetDry", + "RV2530WFB-EU": "Three60WetDry", + "RV2530AWB-EU": "Three60WetDry", + "RV2530WB-EU": "Three60WetDry", + "RV2530AWFB-UK": "Three60WetDry", + "RV2530WFB-UK": "Three60WetDry", + "RV2530AWB-UK": "Three60WetDry", + "RV2530WB-UK": "Three60WetDry", + "RV2810AWFB": "Three60WetDry", + "RV2820AWFB": "Three60WetDry", + "RV2810AWFB-JP": "Three60WetDry", + "RV2820AWFB-JP": "Three60WetDry", + "RV2810AWFB-EU": "Three60WetDry", + "RV2820AWFB-EU": "Three60WetDry", + "RV2810AWFB-UK": "Three60WetDry", + "RV2820AWFB-UK": "Three60WetDry", + "RV2810LEGAL": "Three60WetDry", + "RV2820LEGAL": "Three60WetDry", + "RV2830WFB": "Three60WetDry", + "RV2830WFB-JP": "Three60WetDry", + "RV2830WFB-EU": "Three60WetDry", + "RV2830WFB-UK": "Three60WetDry", + "RV2800AWF-EU": "Three60WetDry", + "RV363LAWBDev": "Three60WetDry", + "RV363LAWFBDev": "Three60WetDry", + "RV363LWFBDev": "Three60WetDry", + "RV363LWBDev": "Three60WetDry", + "RV383LWFBDev": "Three60WetDry", + "RV383LWFBUSDev": "Three60WetDry", + "RV2530AWFB-JP": "Three60WetDry", + "RV2530AWFB-MX": "Three60WetDry", + "RV2530-0000007D": "Three60WetDry", + "RV2530-0000007D-EU": "Three60WetDry", + "RV2530-0000007D-UK": "Three60WetDry", + "RV24SpLABDev": "Three60", + "RV24SpLBDev": "Three60", + "RV2100AB": "Three60", + "RV2100AB-AZ": "Three60", + "RV2100B": "Three60", + "RV2100AB-MX": "Three60", + "RV2100B-MX": "Three60", + "RV2100AB-JP": "Three60", + "RV2100B-JP": "Three60", + "RV2100AB-UK": "Three60", + "RV2100B-UK": "Three60", + "RV2100AB-EU": "Three60", + "RV2100B-EU": "Three60", + "RV2800AWF-JP": "Three60WetDry", + "RV2800AWFX-JP": "Three60WetDry", + "RV2800AW-JP": "Three60WetDry", + "RV2800AWX-JP": "Three60WetDry", + "RV2800AF-JP": "Three60", + "RV2800AFX-JP": "Three60", + "RV2800A-JP": "Three60", + "RV2800AX-JP": "Three60", + "RV2800WF-JP": "Three60WetDry", + "RV2800WFX-JP": "Three60WetDry", + "RV2800W-JP": "Three60WetDry", + "RV2800WX-JP": "Three60WetDry", + "RV2800F-JP": "Three60", + "RV2800FX-JP": "Three60", + "RV2800-JP": "Three60", + "RV2800X-JP": "Three60", + "RV2500AWFB-MX": "Three60WetDry", + "RV2500VAB-MX": "Three60", + "RV2500AAB-MX": "Three60", + "RV2500AAPB-MX": "Three60", + "RV2710AWFB": "Three60WetDry", + "RV2710AWFB-EU": "Three60WetDry", + "RV2710AWFB-UK": "Three60WetDry", + "RV2720AWFB": "Three60WetDry", + "RV2720AWFB-EU": "Three60WetDry", + "RV2720AWFB-UK": "Three60WetDry", + "RV2720-0000B43F": "Three60WetDry", + "RV2720-0000B43F-EU": "Three60WetDry", + "RV2720-0000B43F-UK": "Three60WetDry", + "RV2720-0000B43F-Dev": "Three60WetDry", + "RV2720-0008343F": "Three60WetDry", + "RV2720-0008343F-EU": "Three60WetDry", + "RV2720-0008343F-UK": "Three60WetDry", + "RV2720-0008343F-Dev": "Three60WetDry", + "RV2720-000C143F": "Three60WetDry", + "RV2720-000C143F-EU": "Three60WetDry", + "RV2720-000C143F-UK": "Three60WetDry", + "RV2720-000C143F-Dev": "Three60WetDry", + "RV371LAWFDev": "Three60WetDry", + "RV372LAWFDev": "Three60WetDry", + "RV2900AWFSB": "Three60WetDry", + "RV2900AWFB": "Three60WetDry", + "RV2900AWFSB-EU": "Three60WetDry", + "RV2900AWFSB-UK": "Three60WetDry", + "RV2900AWFB-EU": "Three60WetDry", + "RV2900AWFB-UK": "Three60WetDry", + "RV390LAWFSDev": "Three60WetDry", + "RV390LAWFDev": "Three60WetDry", + "RV3000-001D5F7F": "Three60WetDry", + "RV3000-001F5F7F": "Three60WetDry", + "RV3000-001D5F7F-EU": "Three60WetDry", + "RV3000-001F5F7F-EU": "Three60WetDry", + "RV3000-001D5F7F-UK": "Three60WetDry", + "RV3000-001D5F7F-CA": "Three60WetDry", + "RV3000-001F5F7F-AZ": "Three60WetDry", + "RV3000-001D5F7F-AZ": "Three60WetDry", + "RV2800WA3ACAWAD": "Three60WetDry", + "RV2800WA3ACAWHD": "Three60WetDry", + "RV2800WA3ACHWHD": "Three60WetDry", + "RV2900WA3ACAWAD": "Three60WetDry", + "RV2900WA3ACAWHD": "Three60WetDry", + "RV2900WA3ACHWHD": "Three60WetDry", + "RV2900WA3HCAWAD": "Three60WetDry", + "RV2900WA3HCAWHD": "Three60WetDry", + "RV2900WA3HCHWHD": "Three60WetDry", + "RV2900WA3ACAWAD-EU": "Three60WetDry", + "RV2900WA3ACAWHD-EU": "Three60WetDry", + "RV2900WA3ACHWHD-EU": "Three60WetDry", + "RV2900WA3HCAWAD-EU": "Three60WetDry", + "RV2900WA3HCAWHD-EU": "Three60WetDry", + "RV2900WA3HCHWHD-EU": "Three60WetDry", + "RV2900WA3ACAWAD-UK": "Three60WetDry", + "RV2900WA3ACAWHD-UK": "Three60WetDry", + "RV2900WA3ACHWHD-UK": "Three60WetDry", + "RV2900WA3HCAWAD-UK": "Three60WetDry", + "RV2900WA3HCAWHD-UK": "Three60WetDry", + "RV2900WA3HCHWHD-UK": "Three60WetDry", + "RV2900WA3ACAWAD-AZ": "Three60WetDry", + "RV2900WA3ACAWHD-AZ": "Three60WetDry", + "RV2900WA3ACHWHD-AZ": "Three60WetDry", + "RV2900WA3HCAWAD-AZ": "Three60WetDry", + "RV2900WA3HCAWHD-AZ": "Three60WetDry", + "RV2900WA3HCHWHD-AZ": "Three60WetDry", + "RV2500HOP": "Three60WetDry", + "RV2500HOP-EU": "Three60WetDry", + "RV2500HOPP2B": "Three60WetDry", + "RV2500HOPP2B-EU": "Three60WetDry", + "RV2500HOPP2NB": "Three60WetDry", + "RV2500HOPP2NB-EU": "Three60WetDry", + "RV2500HOPP4CB": "Three60WetDry", + "RV2500HOPP4CB-UK": "Three60WetDry", + "RV2500HOPP4CB-EU": "Three60WetDry", + "RV2800FW3HWHD": "Three60WetDry", + "RV2800FW3HWHD-EU": "Three60WetDry", + "RV2800FW3HWHD-UK": "Three60WetDry", + "RV2800FW3HWHD-CA": "Three60WetDry", + "RV2800FW3AWAD": "Three60WetDry", + "RV2800FW3AWAD-EU": "Three60WetDry", + "RV2800FW3AWAD-UK": "Three60WetDry", + "RV2800FW3AWAD-CA": "Three60WetDry", + "RV2800FW3AWHD": "Three60WetDry", + "RV2800FW3AWHD-EU": "Three60WetDry", + "RV2800FW3AWHD-UK": "Three60WetDry", +} + +_CLASSIFICATIONS: Dict[str, str] = { + "Gaia": "LaserBot", + "Poseidon": "LaserBot", + "Mesa1": "MapBot", + "Mesa2": "MapBot", + "Mesa3": "MapBot", + "MesaAir": "MapBot", + "Valley1": "MapBot", + "Valley2": "MapBot", + "Valley3": "MapBot", + "ValleyAir": "MapBot", + "RandomBounceAV75": "RandomBounce", + "RandomBounceRV75": "RandomBounce", + "RandomBounceRV85": "RandomBounce", + "RandomBounceRV87": "RandomBounce", + "RandomBounceOther": "RandomBounce", + "Three60": "Three60", + "Three60WetDry": "Three60", +} + +# Exact model lists (all Three60-class), as the app's switch statements have them. +RV3000_MODELS: FrozenSet[str] = frozenset( + { + "RV3000-001D5F7F", + "RV3000-001F5F7F", + "RV3000-001D5F7F-EU", + "RV3000-001F5F7F-EU", + "RV3000-001D5F7F-UK", + "RV3000-001D5F7F-CA", + "RV3000-001F5F7F-AZ", + "RV3000-001D5F7F-AZ", + } +) + +OPP_MODELS: FrozenSet[str] = frozenset( + { + "RV2500HOP", + "RV2500HOP-EU", + "RV2500HOPP2B", + "RV2500HOPP2B-EU", + "RV2500HOPP2NB", + "RV2500HOPP2NB-EU", + "RV2500HOPP4CB", + "RV2500HOPP4CB-UK", + "RV2500HOPP4CB-EU", + "RV2530-0000007D", + "RV2530-0000007D-UK", + "RV2530-0000007D-EU", + } +) + +SPOT_LIDAR_MODELS: FrozenSet[str] = frozenset( + { + "RV24SpLABDev", + "RV24SpLBDev", + "RV2100AB", + "RV2100AB-AZ", + "RV2100B", + } +) + +THREE60_EZ_MODELS: FrozenSet[str] = frozenset( + { + "RV360LVADev", + "RV360LVAXDev", + "RV360LAADev", + "RV360LAAXDev", + "RV2500VA", + "RV2500VAX", + "RV2500AA", + "RV2500AAX", + "RV2500VA-JP", + } +) + +ODM_MODELS: FrozenSet[str] = frozenset( + { + "RV2800WA3ACAWAD", + "RV2800WA3ACAWHD", + "RV2800WA3ACHWHD", + "RV2900WA3ACAWAD", + "RV2900WA3ACAWHD", + "RV2900WA3ACHWHD", + "RV2900WA3HCAWAD", + "RV2900WA3HCAWHD", + "RV2900WA3HCHWHD", + "RV2900WA3ACAWAD-EU", + "RV2900WA3ACAWHD-EU", + "RV2900WA3ACHWHD-EU", + "RV2900WA3HCAWAD-EU", + "RV2900WA3HCAWHD-EU", + "RV2900WA3HCHWHD-EU", + "RV2900WA3ACAWAD-UK", + "RV2900WA3ACAWHD-UK", + "RV2900WA3ACHWHD-UK", + "RV2900WA3HCAWAD-UK", + "RV2900WA3HCAWHD-UK", + "RV2900WA3HCHWHD-UK", + "RV2900WA3ACAWAD-AZ", + "RV2900WA3ACAWHD-AZ", + "RV2900WA3ACHWHD-AZ", + "RV2900WA3HCAWAD-AZ", + "RV2900WA3HCAWHD-AZ", + "RV2900WA3HCHWHD-AZ", + } +) + +MPP_MODELS: FrozenSet[str] = frozenset( + { + "RV2800FW3HWHD", + "RV2800FW3HWHD-EU", + "RV2800FW3HWHD-UK", + "RV2800FW3HWHD-CA", + "RV2800FW3AWAD", + "RV2800FW3AWAD-EU", + "RV2800FW3AWAD-UK", + "RV2800FW3AWAD-CA", + "RV2800FW3AWHD", + "RV2800FW3AWHD-EU", + "RV2800FW3AWHD-UK", + } +) + +# Bits of the hex feature mask in models like RV3000-001D5F7F, least significant first. +_MASK_BITS = ("WetDry", "FanJet", "AED", "Series 3", "Bluetooth", "Lidar", "Floor Detect") + +_MAPPING_FAMILIES = frozenset( + {"Gaia", "Poseidon", "Three60", "Three60WetDry", "Mesa1", "Mesa2", "Mesa3", "Valley1", "Valley2", "Valley3"} +) +_EXPLORE_FAMILIES = frozenset({"Gaia", "Poseidon", "Three60", "Three60WetDry"}) +_DND_FAMILIES = _MAPPING_FAMILIES | {"MesaAir", "ValleyAir"} +_VALLEY_FAMILIES = frozenset({"Valley1", "Valley2", "Valley3", "ValleyAir"}) +_MOPPING_FAMILIES = frozenset({"Poseidon", "Three60WetDry"}) + + +@dataclass(frozen=True) +class RobotProfile: + """The app's view of one robot model.""" + + model: str + + @property + def family(self) -> Optional[str]: + """The model's family, or None when the app's table does not list it.""" + return MODEL_FAMILIES.get(self.model) + + @property + def classification(self) -> Optional[str]: + return _CLASSIFICATIONS.get(self.family) if self.family else None + + @property + def known(self) -> bool: + return self.family is not None + + # -- product lines (exact lists; an unlisted model is simply not one) ---- + + def _in(self, models: FrozenSet[str]) -> bool: + return self.classification == "Three60" and self.model in models + + @property + def is_rv3000(self) -> bool: + return self._in(RV3000_MODELS) + + @property + def is_opp(self) -> bool: + return self._in(OPP_MODELS) + + @property + def is_spot_lidar(self) -> bool: + return self._in(SPOT_LIDAR_MODELS) + + @property + def is_360ez(self) -> bool: + return self._in(THREE60_EZ_MODELS) + + # -- hardware from the model string ------------------------------------- + + @property + def _prefix(self) -> str: + return self.model.split("-")[0] + + def _mask(self, bit: str) -> Optional[bool]: + """A bit of the hex feature mask, or None when the model carries none.""" + parts = self.model.split("-") + if len(parts) < 2 or len(parts[1]) < 8: + return None + try: + value = int(parts[1], 16) + except ValueError: + return None + return bool(value >> _MASK_BITS.index(bit) & 1) + + def _family_in(self, families: FrozenSet[str]) -> Optional[bool]: + return None if self.family is None else self.family in families + + def _class_in(self, *classes: str) -> Optional[bool]: + return None if self.classification is None else self.classification in classes + + # -- features, as the app gates them ------------------------------------ + + @property + def has_map(self) -> Optional[bool]: + return self._family_in(_MAPPING_FAMILIES) + + @property + def has_explore(self) -> Optional[bool]: + return self._family_in(_EXPLORE_FAMILIES) + + @property + def has_recharge_resume(self) -> Optional[bool]: + return self._family_in(_MAPPING_FAMILIES) + + @property + def has_auto_empty(self) -> Optional[bool]: + """A self-emptying dock, so Evac & Resume.""" + if self._in(ODM_MODELS) or self._in(MPP_MODELS) or self.is_opp: + return True + masked = self._mask("AED") + if masked is not None: + return masked + if "A" in self._prefix and "VA" not in self._prefix: + return None if self.family is None else self.family not in _VALLEY_FAMILIES + return False + + @property + def has_fan_jet(self) -> bool: + """CleanEdge air jets.""" + masked = self._mask("FanJet") + return masked if masked is not None else "X" in self._prefix + + @property + def do_not_disturb(self) -> Optional[bool]: + return self._family_in(_DND_FAMILIES) + + @property + def has_volume(self) -> Optional[bool]: + """The app shows the volume slider to every robot but random-bounce ones.""" + return None if self.classification is None else self.classification != "RandomBounce" + + @property + def has_pin_drop(self) -> Optional[bool]: + """Spot clean by dropping a pin on the map.""" + if self.is_spot_lidar: + return False + return self._class_in("Three60", "LaserBot") + + @property + def has_ultra_clean(self) -> Optional[bool]: + """Matrix (two-pass) cleaning.""" + if self.is_spot_lidar or self.is_opp: + return False + return self._class_in("Three60", "LaserBot") + + @property + def has_mopping(self) -> Optional[bool]: + return self._family_in(_MOPPING_FAMILIES) + + # RV3000-only settings rows, and OPP-only carpet controls. + + @property + def has_underglow_lights(self) -> bool: + return self.is_rv3000 + + @property + def has_button_sounds(self) -> bool: + return self.is_rv3000 + + @property + def has_carpet_boost(self) -> bool: + return self.is_opp + + @property + def has_carpet_detect(self) -> bool: + return self.is_opp + + +# --------------------------------------------------------------------------- +# Robot types: the few groups every model falls into, for easy configuration +# --------------------------------------------------------------------------- + +#: Robot types, in the order a picker should list them. +ROBOT_TYPES = ("lidar", "lidar_carpet", "rv3000", "spot_lidar", "map", "air", "basic") + + +@dataclass(frozen=True) +class Capabilities: + """What a robot of one type offers, as plain yes/no answers. + + The two hardware extras that vary within a type - a self-emptying dock and + CleanEdge air jets - are asked separately. + """ + + robot_type: str + self_empty_dock: bool + clean_edge: bool + + @property + def _lidar(self) -> bool: + return self.robot_type in ("lidar", "lidar_carpet", "rv3000", "spot_lidar") + + @property + def has_map(self) -> bool: + return self.robot_type not in ("air", "basic") + + @property + def has_rooms(self) -> bool: + return self.has_map + + @property + def has_explore(self) -> bool: + return self._lidar + + @property + def has_pin_drop(self) -> bool: + return self._lidar and self.robot_type != "spot_lidar" + + @property + def has_ultra_clean(self) -> bool: + return self._lidar and self.robot_type not in ("spot_lidar", "lidar_carpet") + + @property + def has_recharge_resume(self) -> bool: + return self.has_map + + @property + def has_auto_empty(self) -> bool: + return self.self_empty_dock + + @property + def has_fan_jet(self) -> bool: + return self.clean_edge + + @property + def do_not_disturb(self) -> bool: + return self.robot_type != "basic" + + @property + def has_volume(self) -> bool: + return self.robot_type != "basic" + + @property + def has_underglow_lights(self) -> bool: + return self.robot_type == "rv3000" + + @property + def has_button_sounds(self) -> bool: + return self.robot_type == "rv3000" + + @property + def has_carpet_boost(self) -> bool: + return self.robot_type == "lidar_carpet" + + @property + def has_carpet_detect(self) -> bool: + return self.robot_type == "lidar_carpet" + + +def robot_type(profile: RobotProfile) -> Optional[str]: + """The robot type a known model belongs to, or None for a model the table lacks.""" + if profile.is_rv3000: + return "rv3000" + if profile.is_opp: + return "lidar_carpet" + if profile.is_spot_lidar: + return "spot_lidar" + if profile.family in ("MesaAir", "ValleyAir"): + return "air" # camera robots without a saved map + return { + "Three60": "lidar", + "LaserBot": "lidar", + "MapBot": "map", + "RandomBounce": "basic", + }.get(profile.classification or "") + + +def capabilities_for_model(model: str) -> Optional[Capabilities]: + """Capabilities straight from a cloud model string, when the table knows it.""" + profile = RobotProfile(model) + kind = robot_type(profile) + if kind is None: + return None + return Capabilities(kind, bool(profile.has_auto_empty), profile.has_fan_jet) diff --git a/sharklocal/mappings/mqtt/sharkiq_v1.yaml b/sharklocal/mappings/mqtt/sharkiq_v1.yaml index aa292fe..8c02c25 100644 --- a/sharklocal/mappings/mqtt/sharkiq_v1.yaml +++ b/sharklocal/mappings/mqtt/sharkiq_v1.yaml @@ -15,27 +15,104 @@ encoding: base64 # Name of the registered decoder function used to parse status payloads. status_decoder: sharkiq_protobuf_v1 -# Maps protobuf OperatingMode integer values to normalized VacuumMode strings. -# Reference: sharkiq.proto OperatingMode enum +# Maps the robot's system state (SysStateT, field 4) to normalized VacuumMode +# strings. Names per sharklocal.codes.SYSTEM_STATES; 6, 7, 13 and 14 have been +# observed on an RV2610BFCA (13 is charging on the dock, 14 battery full). modes: - 6: cleaning - 7: returning_to_dock - 13: docking - 14: docked + 2: idle # SYS_ST_SLEEPING + 3: idle # SYS_ST_WAITING + 4: paused # SYS_ST_PAUSE + 5: error # SYS_ST_ERROR + 6: cleaning # SYS_ST_CLEANING + 7: returning_to_dock # SYS_ST_DOCKING + 8: cleaning # SYS_ST_SPOTING + 9: cleaning # SYS_ST_ALONG_WALL + 13: docked # SYS_ST_CHARGING + 14: docked # SYS_ST_BATTERY_FULL + 15: cleaning # SYS_ST_GO_TARGET + 16: cleaning # SYS_ST_CLEAN_ZONE + 24: exploring # SYS_ST_AUTO_EXPLORE + 25: returning_to_dock # SYS_ST_REDOCKING + 26: returning_to_dock # SYS_ST_EXPLORE_DOCKING + 28: cleaning # SYS_ST_RELOCAL + 29: docking # SYS_ST_BASE_DOCK + 31: exploring # SYS_ST_CARPET_EXPLORE +# Payloads are protobuf. Field 16 is the job command (9 start, 17 return to +# dock); field 7 carries settings, which the robot echoes back in field 8 of +# the next status message. actions: start_cleaning: type: command - payload: "OgQKAhBLgAEJ" + payload: "gAEJ" + # The app bundles a suction change into its start/dock messages; these + # send the bare job command so the setting is left alone. stop: type: command - payload: "OgQKAhAygAER" + payload: "gAER" # go_home issues the same stop-and-return command as stop in this protocol. go_home: type: command - payload: "OgQKAhAygAER" + payload: "gAER" + + # Field 16 is UserCtrlSignalT (sharklocal.codes-style names from the app's + # schema): 8 USR_CTR_PAUSE; start_cleaning above is 9 USR_CTR_RESUME, which + # also resumes a paused job; 16 USR_CTR_ALONG_WALL; 38 USR_CTR_AUTO_EXPLORE. + pause: + type: command + payload: "gAEI" + + edge_clean: + type: command + payload: "gAEQ" + + explore: + type: command + payload: "gAEm" + + # Field 39 = 1: FloorControlT FL_CTR_LOAD_ALL. The robot answers with its + # persisted map (floor type 4) on the status topic. + request_map: + type: command + payload: "uAIB" + + # Field 25 = 104 + find_robot: + type: command + payload: "yAFo" + + # Field 7.1.2 = 50 / 75 / 100 + set_suction_eco: + type: command + payload: "OgQKAhAy" + + set_suction_normal: + type: command + payload: "OgQKAhBL" + + set_suction_max: + type: command + payload: "OgQKAhBk" + + # Field 7.8 = 1 / 2. Reflected by field 35 present / absent in status. + recharge_resume_on: + type: command + payload: "OgJAAQ==" + + recharge_resume_off: + type: command + payload: "OgJAAg==" + + # Field 7.7 = 1 / 2. Reflected by field 36 present / absent in status. + evac_resume_on: + type: command + payload: "OgI4AQ==" + + evac_resume_off: + type: command + payload: "OgI4Ag==" get_status: type: status_request diff --git a/sharklocal/models.py b/sharklocal/models.py index 2d897c5..38d10ac 100644 --- a/sharklocal/models.py +++ b/sharklocal/models.py @@ -2,11 +2,18 @@ from __future__ import annotations -from dataclasses import dataclass, field +import base64 +from dataclasses import asdict, dataclass, field from enum import Enum from typing import Any, Dict, List, Optional +# The app models a Spot Clean as an extra room of this name: a ~1.5 m square +# around the pin. The robot keeps it in its saved map afterwards, marked as the +# room the last job cleaned, until another room definition replaces it. +SPOT_ROOM_NAME = "PinDrop" + + class VacuumMode(str, Enum): """Normalized operating modes across all transports.""" @@ -17,17 +24,57 @@ class VacuumMode(str, Enum): DOCKED = "docked" IDLE = "idle" # Powered on but not cleaning and not on the charging dock EXPLORING = "exploring" # Mapping/exploration run in progress + PAUSED = "paused" # A job paused mid-way + ERROR = "error" # Stopped by a fault + + +class SuctionLevel(str, Enum): + """Suction power levels, named as in the SharkClean app.""" + ECO = "eco" + NORMAL = "normal" + MAX = "max" @dataclass class VacuumStatus: - """Normalized vacuum status, independent of transport protocol.""" + """Normalized vacuum status, independent of transport protocol. + + The optional fields after ``raw`` are only populated by transports that + carry them (currently the SharkIQ MQTT protocol) and stay ``None`` + otherwise. ``map`` is set only on frames that include map data. + """ mode: VacuumMode battery_level: Optional[int] = None charging: Optional[bool] = None raw: Dict[str, Any] = field(default_factory=dict) + job_active: Optional[bool] = None + deep_clean: Optional[bool] = None # Matrix / spot clean in progress + recharge_resume: Optional[bool] = None + evac_resume: Optional[bool] = None + map: Optional["VacuumMap"] = None + # Codes active now (SharkIQ fields 5 and 6); names in sharklocal.codes. + errors: Optional[List[int]] = None + warnings: Optional[List[int]] = None + # SharkIQ device info (field 9), live motor speeds (field 16) and feature + # status, each None when the frame does not carry it. + state: Optional[int] = None # system state (codes.SYSTEM_STATES) + temperature: Optional[int] = None # degrees C + wifi_state: Optional[int] = None # codes.WIFI_STATES + wifi_link_quality: Optional[int] = None + wifi_signal: Optional[int] = None + water_level: Optional[int] = None + dust_level: Optional[int] = None + ip_address: Optional[str] = None + fan_speed: Optional[int] = None # suction motor, live + brushroll_speed: Optional[int] = None + side_brush_speed: Optional[int] = None + clean_edge: Optional[bool] = None # CleanEdge (fan jet) enabled + carpet_detect: Optional[int] = None # codes.CARPET_DETECT_MODES + relocation: Optional[int] = None # codes.RELOCATION_STATES + # Event-log entries streamed mid-job (field 34), when the frame has any. + log_entries: Optional[List["VacuumLogEntry"]] = None @property def is_cleaning(self) -> bool: @@ -38,6 +85,231 @@ def is_docked(self) -> bool: return self.mode in (VacuumMode.DOCKED, VacuumMode.DOCKING) +# --------------------------------------------------------------------------- +# Map models (SharkIQ MQTT map frames) +# --------------------------------------------------------------------------- + + +@dataclass +class MapPoint: + """A point in map world coordinates, in metres.""" + + x: float + y: float + + +@dataclass +class MapPose: + """A position with heading, in metres and radians (0 = +x, anticlockwise).""" + + x: float + y: float + heading: float + + +@dataclass +class MapGrid: + """An occupancy grid, row-major from the map origin (bottom-left). + + ``cells`` holds one byte per cell; ``room_ids`` (persisted maps only) holds + one room segment id per cell, ``0`` meaning unassigned. World-to-cell: + ``col = (x - origin.x) / resolution``, ``row = (y - origin.y) / resolution``. + """ + + resolution: float # metres per cell + width: int + height: int + origin: MapPoint + cells: bytes + room_ids: Optional[bytes] = None + + # Cell values observed in SharkIQ grids. ``CLEANED`` marks floor covered + # by the current (or, on a persisted map, the last) job: every point of + # the cleaned path lands on one, in every captured frame. + UNKNOWN = 0x4B + CLEANED = 0x00 + + @staticmethod + def is_wall(value: int) -> bool: + """``True`` for wall/obstacle cells (``0x50`` and above).""" + return value >= 0x50 + + @staticmethod + def is_floor(value: int) -> bool: + """``True`` for free-floor cells (explored, not wall), cleaned or not.""" + return value < 0x4B + + @staticmethod + def is_cleaned(value: int) -> bool: + """``True`` for floor covered by the job.""" + return value == MapGrid.CLEANED + + @property + def cleaned_cells(self) -> int: + """Number of cells covered by the job.""" + return self.cells.count(MapGrid.CLEANED) + + def cell(self, col: int, row: int) -> int: + """Return the occupancy value at ``(col, row)``.""" + return self.cells[row * self.width + col] + + def room_id(self, col: int, row: int) -> Optional[int]: + """Return the room segment id at ``(col, row)``, or ``None`` if unavailable.""" + if self.room_ids is None: + return None + return self.room_ids[row * self.width + col] + + +@dataclass +class MapRoom: + """A named room as drawn in the app, with its bounding polygon.""" + + name: str + polygon: List[MapPoint] + selected: bool = False # Included in the most recent job + coverage: Optional[float] = None # Fraction cleaned in the most recent job + + +@dataclass +class MapFeature: + """A vector feature of the persisted map — a wall outline or a door.""" + + kind: str # "edge" or "door" + points: List[MapPoint] + + +@dataclass +class VacuumLogEntry: + """One entry of the robot's own event log, carried in the persisted map.""" + + key: str # e.g. "DT_STATE_CHANGE", "DT_WARNING_CODE" + time: int # Unix epoch seconds as reported by the robot + code: str + + +@dataclass +class VacuumMap: + """Map data decoded from a SharkIQ MQTT map frame. + + Live frames (every few seconds during a job) carry the grid, the path + cleaned so far and the robot's pose history. The larger *persisted* frame, + published once when the robot reaches the dock, adds rooms, wall and door + vectors, the dock pose, job statistics and the robot's event log. + """ + + grid: MapGrid + path: List[MapPoint] = field(default_factory=list) + poses: List[MapPose] = field(default_factory=list) + persisted: bool = False + # The end-of-job frame, which alone carries the event log. A persisted map + # sent on request is not a report. + report: bool = False + map_id: Optional[str] = None + name: Optional[str] = None + dock: Optional[MapPose] = None + rooms: List[MapRoom] = field(default_factory=list) + features: List[MapFeature] = field(default_factory=list) + log: List[VacuumLogEntry] = field(default_factory=list) + job_started: Optional[int] = None # Unix epoch seconds + job_minutes: Optional[int] = None # whole minutes, docking included + raw: Dict[str, Any] = field(default_factory=dict) + + @property + def robot(self) -> Optional[MapPose]: + """Current robot pose: the last recorded pose, if any.""" + return self.poses[-1] if self.poses else None + + @property + def named_rooms(self) -> List[MapRoom]: + """The rooms as the app names them — every room except a spot zone.""" + return [room for room in self.rooms if room.name != SPOT_ROOM_NAME] + + @property + def spot(self) -> Optional[MapRoom]: + """The spot-clean zone the robot saved, if the map carries one.""" + return next((room for room in self.rooms if room.name == SPOT_ROOM_NAME), None) + + @property + def cleaned_area(self) -> float: + """Area covered by the job in square metres, counted from the grid.""" + return self.grid.cleaned_cells * self.grid.resolution**2 + + @property + def clean_time(self) -> Optional[int]: + """Seconds spent cleaning in the last job. + + The sum of the event log's ``DT_*_CLEAN_TIME`` entries (normal, + wall-follow and escape cleaning; docking is logged separately). A map + without a log (one sent on request) falls back to the job summary's + whole minutes, which include docking. ``None`` when neither is there. + """ + times = [ + int(entry.code) + for entry in self.log + if entry.key.endswith("_CLEAN_TIME") and entry.code.isdigit() + ] + if times: + return sum(times) + return self.job_minutes * 60 if self.job_minutes else None + + def to_dict(self) -> Dict[str, Any]: + """Return a JSON-serialisable form of the map, for storage. + + The persisted map arrives only when the robot docks, but room and spot + cleaning need its room definition at any time — so a caller that + restarts wants to keep it. Byte rasters are base64-encoded and ``raw`` + is dropped. :meth:`from_dict` reverses this. + """ + data = asdict(self) + data.pop("raw", None) + grid = data["grid"] + grid["cells"] = base64.b64encode(self.grid.cells).decode("ascii") + if self.grid.room_ids is not None: + grid["room_ids"] = base64.b64encode(self.grid.room_ids).decode("ascii") + return data + + @classmethod + def from_dict(cls, data: Dict[str, Any]) -> "VacuumMap": + """Rebuild a map from :meth:`to_dict` output.""" + g = data["grid"] + grid = MapGrid( + resolution=g["resolution"], + width=g["width"], + height=g["height"], + origin=MapPoint(**g["origin"]), + cells=base64.b64decode(g["cells"]), + room_ids=base64.b64decode(g["room_ids"]) if g.get("room_ids") else None, + ) + dock = data.get("dock") + return cls( + grid=grid, + path=[MapPoint(**p) for p in data.get("path", [])], + poses=[MapPose(**p) for p in data.get("poses", [])], + persisted=data.get("persisted", False), + # Stored before this field existed: only reports were persisted then. + report=data.get("report", data.get("persisted", False)), + map_id=data.get("map_id"), + name=data.get("name"), + dock=MapPose(**dock) if dock else None, + rooms=[ + MapRoom( + name=r["name"], + polygon=[MapPoint(**p) for p in r["polygon"]], + selected=r.get("selected", False), + coverage=r.get("coverage"), + ) + for r in data.get("rooms", []) + ], + features=[ + MapFeature(kind=f["kind"], points=[MapPoint(**p) for p in f["points"]]) + for f in data.get("features", []) + ], + log=[VacuumLogEntry(**e) for e in data.get("log", [])], + job_started=data.get("job_started"), + job_minutes=data.get("job_minutes"), + ) + + @dataclass class VacuumEvent: """A single event from the vacuum event log.""" diff --git a/sharklocal/mqtt_client.py b/sharklocal/mqtt_client.py index 9b77d77..0d67798 100644 --- a/sharklocal/mqtt_client.py +++ b/sharklocal/mqtt_client.py @@ -3,13 +3,28 @@ from __future__ import annotations import asyncio +import inspect import base64 -from typing import Any, Callable, Dict, Optional +from typing import Any, Callable, Dict, List, Optional from .exceptions import ActionNotSupportedError, CommandError, ConnectError, DecoderError from .mappings.base import MQTTMappingConfig from .models import VacuumMode, VacuumStatus -from . import protobuf +from . import protobuf, vacuum_map + +# Imported once, here, rather than at first use: importing reads the package +# from disk, and a first use inside Home Assistant's event loop is flagged as a +# blocking call. Still optional, so a REST-only install works without it. +try: + import aiomqtt +except ImportError: # pragma: no cover - exercised by patching this name + aiomqtt = None # type: ignore[assignment] + + +def _require_aiomqtt() -> Any: + if aiomqtt is None: + raise ConnectError("aiomqtt is required for MQTT support. Install with: pip install aiomqtt") + return aiomqtt # Registry mapping decoder name -> callable(payload_bytes, modes) -> VacuumStatus. @@ -43,13 +58,33 @@ def _decode_sharkiq_protobuf_v1( Field reference: - * Field 4 — ``OperatingMode`` integer + * Field 4 — system state (``SysStateT``, see :mod:`sharklocal.codes`) + * Field 5 — error codes active now (repeated ``ErrorCodeT``) + * Field 6 — warning codes active now (repeated ``WarningCodeT``) * Field 9 — ``BatteryInfo`` nested message * Field 1 — ``ChargingState`` (3 = ``CHARGING_ON_DOCK``) * Field 8 — ``battery_percent`` (0–100) + + * Field 35 — present (``2``) while Recharge & Resume is enabled + * Field 36 — present (``2``) while Evac & Resume is enabled + * Field 40 — ``2`` normal clean / ``1`` Matrix or Spot clean (during a job) + * Field 45 — ``2`` while a job is active, ``0`` otherwise + * Field 7 — map data on map-bearing frames (see :mod:`sharklocal.vacuum_map`) """ + fields = protobuf.decode_fields(payload) + + # Map frames are large binary blobs that decode_raw would mis-parse as + # nested messages; decode them separately and keep them out of ``raw``. + map_blob = fields.pop(vacuum_map.FIELD_MAP, None) + decoded_map = None + if map_blob is not None: + decoded_map = vacuum_map.decode_map({vacuum_map.FIELD_MAP: map_blob, **fields}) + payload = protobuf.remove_field(payload, vacuum_map.FIELD_MAP) + raw = protobuf.decode_raw(payload) + errors = _repeated_varints(fields.get(5, [])) + warnings = _repeated_varints(fields.get(6, [])) mode_int = raw.get(4, 0) mode_str = modes.get(mode_int, "unknown") @@ -58,22 +93,115 @@ def _decode_sharkiq_protobuf_v1( except ValueError: mode = VacuumMode.UNKNOWN - battery_info = raw.get(9, {}) - battery_percent: Optional[int] = None - charging: Optional[bool] = None - if isinstance(battery_info, dict): - battery_percent = battery_info.get(8) - charging_state = battery_info.get(1, 0) - charging = charging_state == 3 # ChargingState.CHARGING_ON_DOCK + # Field 9 is device info. Its field 1 is the Wi-Fi state, not a charging + # state (it reads 3, WIFI_CONNECTED, while the robot cleans); charging is + # the system state SYS_ST_CHARGING. + device = _submessage(fields, 9) + battery_percent: Optional[int] = _first_int(device, 8) + charging: Optional[bool] = (mode_int == 13) if 4 in raw else None + base = _submessage(fields, 16) + + # Settings are reflected by presence: the field disappears when switched off. + recharge_resume = 35 in raw + evac_resume = 36 in raw + job_active = raw.get(45) == 2 + deep_clean: Optional[bool] = None + if 40 in raw: + deep_clean = raw[40] == 1 return VacuumStatus( mode=mode, battery_level=battery_percent, charging=charging, raw={"protobuf_fields": raw}, + job_active=job_active, + deep_clean=deep_clean, + recharge_resume=recharge_resume, + evac_resume=evac_resume, + map=decoded_map, + errors=errors, + warnings=warnings, + state=raw.get(4), + temperature=_first_int(device, 11), + wifi_state=_first_int(device, 1), + wifi_link_quality=_first_int(device, 2), + wifi_signal=_first_int(device, 3), + water_level=_first_int(device, 9), + dust_level=_first_int(device, 10), + ip_address=_first_text(device, 17), + fan_speed=_first_int(base, 3), + brushroll_speed=_first_int(base, 5), + side_brush_speed=_first_int(base, 6), + clean_edge=_toggle(raw.get(43)), + carpet_detect=raw.get(44), + relocation=raw.get(41), + log_entries=_diagnose_entries(fields.get(34)), ) +def _diagnose_entries(values: Optional[list]) -> Optional[list]: + """Field 34 (repeated PbDiagnoseInfo): its field 5 holds JSON log entries.""" + if not values: + return None + entries = [] + for value in values: + if not isinstance(value, bytes): + continue + try: + info = protobuf.decode_fields(value) + except Exception: # noqa: BLE001 - a malformed record is skipped + continue + for text in info.get(5, []): + if isinstance(text, bytes): + entries.extend(vacuum_map.parse_log_json(text)) + return entries + + +def _submessage(fields: Dict[int, list], num: int) -> Dict[int, list]: + """The fields of a nested message, or an empty dict.""" + value = fields.get(num, [None])[0] + if not isinstance(value, bytes): + return {} + try: + return protobuf.decode_fields(value) + except Exception: # noqa: BLE001 - a malformed sub-message is just absent + return {} + + +def _first_int(fields: Dict[int, list], num: int) -> Optional[int]: + value = fields.get(num, [None])[0] + return value if isinstance(value, int) else None + + +def _first_text(fields: Dict[int, list], num: int) -> Optional[str]: + value = fields.get(num, [None])[0] + if not isinstance(value, bytes): + return None + try: + return value.decode("utf-8") + except UnicodeDecodeError: + return None + + +def _toggle(value: Any) -> Optional[bool]: + """A PbToggleT: 1 on, 2 off, anything else unknown.""" + return {1: True, 2: False}.get(value) + + +def _repeated_varints(values: list) -> List[int]: + """Values of a repeated varint field, packed (one bytes blob) or not.""" + out: List[int] = [] + for value in values: + if isinstance(value, int): + out.append(value) + continue + pos = 0 + while pos < len(value): + number, pos = protobuf._decode_varint(value, pos) + out.append(number) + return out + + class MQTTVacuumClient: """Async MQTT client for local vacuum control. @@ -127,17 +255,11 @@ async def call(self, action: str) -> Any: spec = self.mapping.actions[action] - try: - import aiomqtt - except ImportError as exc: - raise ConnectError( - "aiomqtt is required for MQTT support. " - "Install with: pip install aiomqtt" - ) from exc + mqtt = _require_aiomqtt() try: if spec.type == "command": - async with aiomqtt.Client(self.host, port=self.mapping.port) as client: + async with mqtt.Client(self.host, port=self.mapping.port) as client: await client.publish(self.mapping.command_topic, payload=spec.payload) return True @@ -153,14 +275,37 @@ async def call(self, action: str) -> Any: raise CommandError(f"Unrecognised MQTT action type '{spec.type}'") + async def send(self, payload: bytes) -> bool: + """Publish a raw command payload that is built at runtime. + + Used for commands whose content depends on state — room selection + carries the map's room definition — and so cannot be a fixed mapping + action. *payload* is the protobuf message bytes; it is encoded per the + mapping's ``encoding`` before publishing. + + Raises: + ConnectError: If the MQTT broker cannot be reached. + """ + mqtt = _require_aiomqtt() + + encoded: Any = payload + if self.mapping.encoding == "base64": + encoded = base64.b64encode(payload).decode("ascii") + + try: + async with mqtt.Client(self.host, port=self.mapping.port) as client: + await client.publish(self.mapping.command_topic, payload=encoded) + except Exception as exc: + raise ConnectError( + f"MQTT error connecting to {self.host}:{self.mapping.port}: {exc}" + ) from exc + return True + async def _request_status(self, command_payload: str, timeout: float) -> VacuumStatus: """Publish a status-request command and return the decoded first response.""" - try: - import aiomqtt - except ImportError as exc: - raise ConnectError("aiomqtt is required for MQTT support") from exc + mqtt = _require_aiomqtt() - async with aiomqtt.Client(self.host, port=self.mapping.port) as client: + async with mqtt.Client(self.host, port=self.mapping.port) as client: await client.subscribe(self.mapping.status_topic) await client.publish(self.mapping.command_topic, payload=command_payload) try: @@ -190,13 +335,10 @@ async def monitor( stop_event: Optional ``asyncio.Event``; when set, monitoring stops cleanly after the current message. """ - try: - import aiomqtt - except ImportError as exc: - raise ConnectError("aiomqtt is required for MQTT support") from exc + mqtt = _require_aiomqtt() try: - async with aiomqtt.Client(self.host, port=self.mapping.port) as client: + async with mqtt.Client(self.host, port=self.mapping.port) as client: await client.subscribe(self.mapping.status_topic) async for message in client.messages: if stop_event and stop_event.is_set(): @@ -205,7 +347,7 @@ async def monitor( status = self._decode_status(bytes(message.payload)) except (DecoderError, CommandError): continue # Skip malformed messages silently - if asyncio.iscoroutinefunction(callback): + if inspect.iscoroutinefunction(callback): await callback(status) else: callback(status) diff --git a/sharklocal/protobuf.py b/sharklocal/protobuf.py index f89436f..6c8ca54 100644 --- a/sharklocal/protobuf.py +++ b/sharklocal/protobuf.py @@ -1,13 +1,20 @@ -"""Pure-Python protobuf decoder for SharkIQ MQTT messages. +"""Pure-Python protobuf codec for SharkIQ MQTT messages. -Decodes raw protobuf wire format without a compiled schema. +Decodes raw protobuf wire format without a compiled schema, and encodes the +few field shapes needed to build command payloads. Adapted for the SharkIQ local MQTT protocol. """ from __future__ import annotations import struct -from typing import Any, Dict, Tuple +from typing import Any, Dict, List, Tuple + +# Wire types, per the protobuf encoding specification. +WIRE_VARINT = 0 +WIRE_FIXED64 = 1 +WIRE_LENGTH_DELIMITED = 2 +WIRE_FIXED32 = 5 def _decode_varint(data: bytes, pos: int) -> Tuple[int, int]: @@ -76,3 +83,126 @@ def decode_raw(data: bytes) -> Dict[int, Any]: break # pragma: no cover return result + + +def decode_fields(data: bytes) -> Dict[int, List[Any]]: + """Decode one protobuf message level, keeping every occurrence of a field. + + Unlike :func:`decode_raw`, this does **not** recurse into length-delimited + fields and does **not** collapse repeated fields — each field number maps + to the list of values in wire order. Length-delimited values are returned + as ``bytes`` for the caller to interpret (nested message, string, or a + packed binary blob such as a map raster), and 32-bit fixed values are + returned as the raw unsigned integer (see :func:`float32`). + + Use this for messages whose layout is known, where ``decode_raw``'s + heuristics would mis-parse binary blobs or drop repeated entries. + """ + result: Dict[int, List[Any]] = {} + pos = 0 + + while pos < len(data): + tag, pos = _decode_varint(data, pos) + field_num = tag >> 3 + wire_type = tag & 0x7 + + if wire_type == WIRE_VARINT: + value, pos = _decode_varint(data, pos) + elif wire_type == WIRE_FIXED64: + value = struct.unpack(" float: + """Reinterpret a decoded 32-bit fixed field as an IEEE-754 ``float``.""" + return struct.unpack(" bytes: + """Return *data* with every top-level occurrence of *field_num* removed. + + Other fields are copied byte-for-byte, so the result decodes identically + apart from the dropped field. Parsing stops at an unknown wire type, and + the remainder is kept as-is. + """ + out = bytearray() + pos = 0 + + while pos < len(data): + start = pos + tag, pos = _decode_varint(data, pos) + wire_type = tag & 0x7 + + if wire_type == WIRE_VARINT: + _, pos = _decode_varint(data, pos) + elif wire_type == WIRE_FIXED64: + pos += 8 + elif wire_type == WIRE_LENGTH_DELIMITED: + length, pos = _decode_varint(data, pos) + pos += length + elif wire_type == WIRE_FIXED32: + pos += 4 + else: + out += data[start:] + break + + if (tag >> 3) != field_num: + out += data[start:pos] + + return bytes(out) + + +# --------------------------------------------------------------------------- +# Encoding — enough to build command payloads +# --------------------------------------------------------------------------- + + +def encode_varint(value: int) -> bytes: + """Encode a non-negative integer as a protobuf varint.""" + out = bytearray() + while True: + byte = value & 0x7F + value >>= 7 + if value: + out.append(byte | 0x80) + else: + out.append(byte) + return bytes(out) + + +def encode_varint_field(field_num: int, value: int) -> bytes: + """Encode ``field_num`` as a varint field.""" + return encode_varint((field_num << 3) | WIRE_VARINT) + encode_varint(value) + + +def encode_float_field(field_num: int, value: float) -> bytes: + """Encode ``field_num`` as a 32-bit ``float`` field.""" + return encode_varint((field_num << 3) | WIRE_FIXED32) + struct.pack(" bytes: + """Encode ``field_num`` as a length-delimited field (nested message or bytes).""" + return ( + encode_varint((field_num << 3) | WIRE_LENGTH_DELIMITED) + + encode_varint(len(content)) + + content + ) + + +def encode_string_field(field_num: int, text: str) -> bytes: + """Encode ``field_num`` as a UTF-8 string field.""" + return encode_bytes_field(field_num, text.encode("utf-8")) diff --git a/sharklocal/rest_client.py b/sharklocal/rest_client.py index ee91773..5f121d6 100644 --- a/sharklocal/rest_client.py +++ b/sharklocal/rest_client.py @@ -11,6 +11,8 @@ from .mappings.base import RESTMappingConfig from .models import DeviceInfo, VacuumEvent, VacuumMode, VacuumStatus +REST_REQUEST_TIMEOUT = 5.0 + class RESTVacuumClient: """Async HTTP/HTTPS client for local vacuum control via the REST API. @@ -24,6 +26,15 @@ def __init__(self, host: str, mapping: RESTMappingConfig) -> None: self.host = host self.mapping = mapping self._session: Optional[aiohttp.ClientSession] = None + # Building an SSL context reads the system certificate store, which is + # blocking I/O; doing it here keeps it out of the event loop for callers + # (Home Assistant) that construct clients in an executor. + self._ssl_context: Optional[ssl.SSLContext] = None + if mapping.transport != "http": + self._ssl_context = ssl.create_default_context() + if not mapping.verify_ssl: + self._ssl_context.check_hostname = False + self._ssl_context.verify_mode = ssl.CERT_NONE @property def base_url(self) -> str: @@ -35,18 +46,16 @@ def supports(self, action: str) -> bool: def _make_connector(self) -> aiohttp.TCPConnector: """Build a ``TCPConnector`` with SSL settings from the mapping.""" - if self.mapping.transport == "http": + if self._ssl_context is None: return aiohttp.TCPConnector() - if not self.mapping.verify_ssl: - ctx = ssl.create_default_context() - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE - return aiohttp.TCPConnector(ssl=ctx) - return aiohttp.TCPConnector() + return aiohttp.TCPConnector(ssl=self._ssl_context) async def _get_session(self) -> aiohttp.ClientSession: if self._session is None or self._session.closed: - self._session = aiohttp.ClientSession(connector=self._make_connector()) + self._session = aiohttp.ClientSession( + connector=self._make_connector(), + timeout=aiohttp.ClientTimeout(total=REST_REQUEST_TIMEOUT), + ) return self._session async def close(self) -> None: @@ -98,7 +107,11 @@ async def call(self, action: str) -> Any: except Exception: return True - except aiohttp.ClientConnectorError as exc: + except (aiohttp.ClientConnectionError, TimeoutError) as exc: + # Not just a refused connection: a robot that drops packets (seen + # during the nightly network restart) times out instead, and that + # is just as unreachable. Anything else escaping here skips the + # MQTT fallback and fails the caller's setup outright. raise ConnectError( f"Cannot connect to vacuum at {self.host}:{self.mapping.port}" ) from exc diff --git a/sharklocal/vacuum_map.py b/sharklocal/vacuum_map.py new file mode 100644 index 0000000..a3e0d04 --- /dev/null +++ b/sharklocal/vacuum_map.py @@ -0,0 +1,380 @@ +"""Map decoding and room-command encoding for the SharkIQ MQTT protocol. + +The robot publishes two kinds of map-bearing frames on the status topic, both +inside top-level field ``7``: + +* **Live frames** (~27 KB, every few seconds while a job runs) — the occupancy + grid, the path cleaned so far and the robot's pose history. +* **Persisted frame** (~92 KB, once, as the robot reaches the dock; flagged by + top-level field ``3 = 1``) — the saved map with rooms, wall and door vectors, + the dock pose, job statistics and the robot's own event log. +* **Requested map** (~97 KB, on request: ``VacuumClient.request_map()``) — the + same saved map, including the last job's path and summary, but without the + event log or the field ``3`` flag. The floor's own type (``7.4``) says it is + the persisted map. + +Coordinates are metres in the map frame; ``cell = (m - origin) / resolution``. +Everything here was reverse-engineered from live captures, so field meanings +are documented at the point of use rather than by a ``.proto`` name. +""" + +from __future__ import annotations + +import json +import struct +from typing import Any, Dict, List, Optional + +from . import protobuf +from .models import ( + MapFeature, + MapGrid, + MapPoint, + MapPose, + MapRoom, + SPOT_ROOM_NAME, + VacuumLogEntry, + VacuumMap, +) + +# Top-level fields of a status frame that carry map data. +FIELD_MAP = 7 +FIELD_PERSISTED_FLAG = 3 + +# Field 7.4 is the floor's MapTypeT (the app's schema): 1 MT_RT_UPLOAD (live), +# 2 MT_REPORT (the end-of-job frame), 4 MT_PERSIST (the saved map, as sent on +# request). +MAP_TYPE_PERSIST = 4 + +# Room-record fields the app adds to a room selected for Matrix (deep) Clean. +_DEEP_CLEAN_FIELDS = ((7, 2), (9, 0), (10, 2)) +# Spot Clean is a synthetic room of this name with a square polygon around the pin. +SPOT_HALF_SIZE = 0.762 # metres — the app draws a ~1.5 m square + + +def _fields(data: bytes) -> Dict[int, List[Any]]: + return protobuf.decode_fields(data) + + +def _first(fields: Dict[int, List[Any]], num: int, default: Any = None) -> Any: + values = fields.get(num) + return values[0] if values else default + + +def _text(value: Optional[bytes]) -> Optional[str]: + return value.decode("utf-8", errors="replace") if value is not None else None + + +# --------------------------------------------------------------------------- +# Decoding +# --------------------------------------------------------------------------- + + +def has_map(fields: Dict[int, List[Any]]) -> bool: + """``True`` if a decoded status frame carries an occupancy grid.""" + blob = _first(fields, FIELD_MAP) + return isinstance(blob, bytes) and _drawable(_first(_fields(blob), 5)) + + +def _drawable(grid_blob: Any) -> bool: + """A grid with cells to draw. A job opens with a live frame whose grid is + empty (no resolution, size or cells, measured on a Matrix clean): that + says the job's map starts afresh, not that there is one to draw.""" + if not isinstance(grid_blob, bytes): + return False + g = _fields(grid_blob) + return bool(_first(g, 6)) and bool(_first(g, 3)) and bool(_first(g, 4)) and 1 in g + + +def decode_map(fields: Dict[int, List[Any]]) -> Optional[VacuumMap]: + """Decode the map carried in a status frame. + + Args: + fields: The frame as returned by :func:`sharklocal.protobuf.decode_fields`. + + Returns: + A :class:`~sharklocal.models.VacuumMap`, or ``None`` if the frame has + no grid (ordinary status frames). + """ + blob = _first(fields, FIELD_MAP) + if not isinstance(blob, bytes): + return None + m = _fields(blob) + if not _drawable(_first(m, 5)): + return None + + grid = _decode_grid(m[5][0]) + report = _first(fields, FIELD_PERSISTED_FLAG) == 1 + persisted = report or _first(m, 4) == MAP_TYPE_PERSIST + + vacuum_map = VacuumMap( + grid=grid, + path=_decode_points(_first(m, 8)), + poses=_decode_poses(_first(m, 10)), + persisted=persisted, + report=report, + map_id=_text(_first(m, 3)), + name=_text(_first(m, 2)), + dock=_decode_pose_f32(_first(m, 7)), + rooms=[_decode_room(r) for r in m.get(15, [])], + features=[f for f in (_decode_feature(r) for r in m.get(28, [])) if f], + ) + + # Field 21 is the persisted grid; its sub-field 19 is the room-id raster. + persisted_grid = _first(m, 21) + if isinstance(persisted_grid, bytes): + g21 = _fields(persisted_grid) + room_ids = _first(g21, 19) + if isinstance(room_ids, bytes) and len(room_ids) == len(grid.cells): + grid.room_ids = room_ids + + # Field 11 is PbMapSummary (the app's schema): .1 beginTime, .2 + # currentCleanTime, .3 currentArea, .4-.6 lifetime totals. .2 is whole + # minutes of the job, docking included: 3 for a job that ran 216 s and + # logged 101 s of cleaning. .3 is not decoded: cleaned area comes from the + # grid (2709 against 25.6 m2 of cleaned cells suggests 0.01 m2, unconfirmed). + stats = _first(m, 11) + if isinstance(stats, bytes): + summary = _fields(stats) + vacuum_map.job_started = _first(summary, 1) + vacuum_map.job_minutes = _first(summary, 2) + + # Field 20.3.6 is the robot's event log as a JSON array of {key, time, code}. + vacuum_map.log = _decode_log(_first(m, 20)) + + return vacuum_map + + +def _decode_grid(data: bytes) -> MapGrid: + """Field 7.5: ``.1`` resolution f32, ``.2`` origin {x,y} f32, ``.3``/``.4`` + width/height, ``.6`` one byte per cell.""" + g = _fields(data) + origin = _fields(_first(g, 2, b"")) + return MapGrid( + resolution=protobuf.float32(_first(g, 1, 0)), + width=_first(g, 3, 0), + height=_first(g, 4, 0), + origin=MapPoint( + protobuf.float32(_first(origin, 1, 0)), + protobuf.float32(_first(origin, 2, 0)), + ), + cells=_first(g, 6, b""), + ) + + +def _decode_int16_list(data: Optional[bytes], stride: int) -> List[tuple]: + """Fields 7.8 / 7.10: ``.1`` scale f32, ``.3`` packed little-endian int16 tuples. + + Every component (metres, and radians for the heading) is ``int16 * scale``. + """ + if not isinstance(data, bytes): + return [] + p = _fields(data) + scale = protobuf.float32(_first(p, 1, 0)) + raw = _first(p, 3, b"") + count = len(raw) // (2 * stride) + values = struct.unpack(f"<{count * stride}h", raw[: count * stride * 2]) + return [ + tuple(v * scale for v in values[i : i + stride]) + for i in range(0, count * stride, stride) + ] + + +def _decode_points(data: Optional[bytes]) -> List[MapPoint]: + return [MapPoint(x, y) for x, y in _decode_int16_list(data, 2)] + + +def _decode_poses(data: Optional[bytes]) -> List[MapPose]: + return [MapPose(x, y, h) for x, y, h in _decode_int16_list(data, 3)] + + +def _decode_pose_f32(data: Optional[bytes]) -> Optional[MapPose]: + """Field 7.7: ``.1`` x, ``.2`` y, ``.3`` heading — all f32.""" + if not isinstance(data, bytes): + return None + p = _fields(data) + return MapPose( + protobuf.float32(_first(p, 1, 0)), + protobuf.float32(_first(p, 2, 0)), + protobuf.float32(_first(p, 3, 0)), + ) + + +def _decode_point_f32(data: bytes) -> MapPoint: + """``.1`` x f32, ``.2`` y f32 — used by room polygons and features.""" + p = _fields(data) + return MapPoint( + protobuf.float32(_first(p, 1, 0)), + protobuf.float32(_first(p, 2, 0)), + ) + + +def _decode_room(data: bytes) -> MapRoom: + """Field 7.15: ``.2`` name, ``.4`` polygon of ``.1`` points, ``.5`` selected, + ``.6`` coverage fraction (f32).""" + r = _fields(data) + polygon = _fields(_first(r, 4, b"")) + coverage = _first(r, 6) + return MapRoom( + name=_text(_first(r, 2, b"")) or "", + polygon=[_decode_point_f32(pt) for pt in polygon.get(1, [])], + selected=_first(r, 5) == 1, + coverage=protobuf.float32(coverage) if coverage is not None else None, + ) + + +def _decode_feature(data: bytes) -> Optional[MapFeature]: + """Field 7.28: ``.2`` kind ("edge" / "door"), ``.4`` polyline of ``.1`` points.""" + f = _fields(data) + kind = _text(_first(f, 2)) + polyline = _first(f, 4) + if kind is None or not isinstance(polyline, bytes): + return None + points = [_decode_point_f32(pt) for pt in _fields(polyline).get(1, [])] + return MapFeature(kind=kind, points=points) + + +def _decode_log(data: Optional[bytes]) -> List[VacuumLogEntry]: + """Field 7.20.3.6: JSON ``[{"key": ..., "time": "s", "code": ...}]``.""" + if not isinstance(data, bytes): + return [] + inner = _first(_fields(data), 3) + if not isinstance(inner, bytes): + return [] + text = _first(_fields(inner), 6) + if not isinstance(text, bytes): + return [] + return parse_log_json(text) + + +def parse_log_json(text: bytes) -> List[VacuumLogEntry]: + """Parse the robot's JSON log format: ``[{"key", "time": "s", "code"}]``. + + The persisted map carries the job's whole log this way; status frames can + carry entries mid-job too (field 34). + """ + try: + entries = json.loads(text.decode("utf-8", errors="replace")) + except ValueError: + return [] + if not isinstance(entries, list): + return [] + log: List[VacuumLogEntry] = [] + for entry in entries: + if not isinstance(entry, dict): + continue + time_text = str(entry.get("time", "0")).rstrip("s") + log.append( + VacuumLogEntry( + key=str(entry.get("key", "")), + time=int(time_text) if time_text.isdigit() else 0, + code=str(entry.get("code", "")), + ) + ) + return log + + +# --------------------------------------------------------------------------- +# Encoding — room and spot selection +# --------------------------------------------------------------------------- + + +def _encode_point(point: MapPoint) -> bytes: + return protobuf.encode_bytes_field( + 1, + protobuf.encode_float_field(1, point.x) + protobuf.encode_float_field(2, point.y), + ) + + +def _encode_room(room: MapRoom, *, deep: bool, spot: bool = False) -> bytes: + """One field-15 room record, in the shape the app sends it.""" + polygon = b"".join(_encode_point(pt) for pt in room.polygon) + record = ( + protobuf.encode_string_field(2, room.name) + + protobuf.encode_string_field(3, room.name) + + protobuf.encode_bytes_field(4, polygon) + ) + if deep or spot: + for num, value in _DEEP_CLEAN_FIELDS: + record += protobuf.encode_varint_field(num, value) + if spot and num == 7: + record += protobuf.encode_varint_field(8, 1) + return record + + +def encode_room_selection( + vacuum_map: VacuumMap, + room_names: List[str], + *, + deep: bool = False, +) -> bytes: + """Build the "set cleaning area" message for a room clean. + + Mirrors what the SharkClean app publishes before ``start_cleaning``: the + map's full room definition (field ``6``), the command ``16 = 11``, and the + selected room names in field ``41``. Rooms named in *room_names* are marked + for Matrix Clean when *deep* is set. + + Args: + vacuum_map: A persisted map carrying the room definition. + room_names: Names of the rooms to clean, as shown in the app. + deep: Request a Matrix (two-pass) clean of the selected rooms. + + Raises: + ValueError: If a name is not a room of *vacuum_map*, or the map has no id. + """ + if vacuum_map.map_id is None: + raise ValueError("Map has no id; room cleaning needs a persisted map") + # A spot zone left in the saved map is not a room anyone can choose, and + # is not re-uploaded: the definition sent is the app's rooms alone. + known = {room.name: room for room in vacuum_map.named_rooms} + missing = [name for name in room_names if name not in known] + if missing: + raise ValueError(f"Unknown room(s) {missing}; map has {sorted(known)}") + + rooms = b"".join( + protobuf.encode_bytes_field( + 15, _encode_room(room, deep=deep and room.name in room_names) + ) + for room in vacuum_map.named_rooms + ) + return _encode_selection(vacuum_map.map_id, rooms, room_names) + + +def spot_polygon(x: float, y: float) -> List[MapPoint]: + """The square the app sends for a Spot Clean centred on ``(x, y)``.""" + d = SPOT_HALF_SIZE + return [ + MapPoint(x - d, y + d), + MapPoint(x + d, y + d), + MapPoint(x + d, y - d), + MapPoint(x - d, y - d), + ] + + +def encode_spot_selection(vacuum_map: VacuumMap, x: float, y: float) -> bytes: + """Build the "set cleaning area" message for a Spot Clean centred on ``(x, y)``. + + The app models a spot clean as an extra room named ``"PinDrop"`` with a + square polygon around the pin, appended to the map's room definition. + """ + if vacuum_map.map_id is None: + raise ValueError("Map has no id; spot cleaning needs a persisted map") + spot = MapRoom(name=SPOT_ROOM_NAME, polygon=spot_polygon(x, y)) + # The previous spot zone, if the saved map still has one, is replaced. + rooms = b"".join( + protobuf.encode_bytes_field(15, _encode_room(room, deep=False)) + for room in vacuum_map.named_rooms + ) + protobuf.encode_bytes_field(15, _encode_room(spot, deep=True, spot=True)) + return _encode_selection(vacuum_map.map_id, rooms, [SPOT_ROOM_NAME]) + + +def _encode_selection(map_id: str, rooms: bytes, names: List[str]) -> bytes: + definition = protobuf.encode_string_field(3, map_id) + rooms + selection = b"".join(protobuf.encode_string_field(1, name) for name in names) + selection += protobuf.encode_string_field(3, map_id) + return ( + protobuf.encode_bytes_field(6, definition) + + protobuf.encode_varint_field(16, 11) + + protobuf.encode_varint_field(39, 2) + + protobuf.encode_bytes_field(41, selection) + ) diff --git a/tests/fixtures/sharkiq_cmd_room_clean.b64 b/tests/fixtures/sharkiq_cmd_room_clean.b64 new file mode 100644 index 0000000..6fb27e0 --- /dev/null +++ b/tests/fixtures/sharkiq_cmd_room_clean.b64 @@ -0,0 +1 @@ +MqwCGggzQ0RCQkM1OXpKEgpCYXRocm9vbS4gGgpCYXRocm9vbS4gIjAKCg0PqB7AFau6dUAKCg1actq+Fau6dUAKCg1actq+FfL8tj8KCg0PqB7AFQH9tj96PhIEUm9vbRoEUm9vbSIwCgoNJIjfwBUfOJJACgoNX78nwBUfOJJACgoNX78nwBX9DZS/CgoNJIjfwBX9DZS/ek4SDExhdW5kcnkgUm9vbRoMTGF1bmRyeSBSb29tIjAKCg2WqHo/FZzB5D8KCg3xL5BAFZzB5D8KCg3xL5BAFQuq3r8KCg2WqHo/FQuq3r96RBIHSGFsbHdheRoHSGFsbHdheSIwCgoNqNIrwBUj3rg/CgoNjmt+PxUj3rg/CgoNjmt+PxVqdALACgoNqNIrwBVqdALAgAELuAICygIWCgpCYXRocm9vbS4gGggzQ0RCQkM1OQ== \ No newline at end of file diff --git a/tests/fixtures/sharkiq_cmd_room_clean_matrix.b64 b/tests/fixtures/sharkiq_cmd_room_clean_matrix.b64 new file mode 100644 index 0000000..a9b1bfa --- /dev/null +++ b/tests/fixtures/sharkiq_cmd_room_clean_matrix.b64 @@ -0,0 +1 @@ +MrICGggzQ0RCQkM1OXpQEgpCYXRocm9vbS4gGgpCYXRocm9vbS4gIjAKCg0PqB7AFau6dUAKCg1actq+Fau6dUAKCg1actq+FfL8tj8KCg0PqB7AFQH9tj84AkgAUAJ6PhIEUm9vbRoEUm9vbSIwCgoNJIjfwBUfOJJACgoNX78nwBUfOJJACgoNX78nwBX9DZS/CgoNJIjfwBX9DZS/ek4SDExhdW5kcnkgUm9vbRoMTGF1bmRyeSBSb29tIjAKCg2WqHo/FZzB5D8KCg3xL5BAFZzB5D8KCg3xL5BAFQuq3r8KCg2WqHo/FQuq3r96RBIHSGFsbHdheRoHSGFsbHdheSIwCgoNqNIrwBUj3rg/CgoNjmt+PxUj3rg/CgoNjmt+PxVqdALACgoNqNIrwBVqdALAgAELuAICygIWCgpCYXRocm9vbS4gGggzQ0RCQkM1OQ== \ No newline at end of file diff --git a/tests/fixtures/sharkiq_cmd_spot_clean.b64 b/tests/fixtures/sharkiq_cmd_spot_clean.b64 new file mode 100644 index 0000000..f07a75b --- /dev/null +++ b/tests/fixtures/sharkiq_cmd_spot_clean.b64 @@ -0,0 +1 @@ +MvoCGggzQ0RCQkM1OXpKEgpCYXRocm9vbS4gGgpCYXRocm9vbS4gIjAKCg0PqB7AFau6dUAKCg1actq+Fau6dUAKCg1actq+FfL8tj8KCg0PqB7AFQH9tj96PhIEUm9vbRoEUm9vbSIwCgoNJIjfwBUfOJJACgoNX78nwBUfOJJACgoNX78nwBX9DZS/CgoNJIjfwBX9DZS/ek4SDExhdW5kcnkgUm9vbRoMTGF1bmRyeSBSb29tIjAKCg2WqHo/FZzB5D8KCg3xL5BAFZzB5D8KCg3xL5BAFQuq3r8KCg2WqHo/FQuq3r96RBIHSGFsbHdheRoHSGFsbHdheSIwCgoNqNIrwBUj3rg/CgoNjmt+PxUj3rg/CgoNjmt+PxVqdALACgoNqNIrwBVqdALAekwSB1BpbkRyb3AaB1BpbkRyb3AiMAoKDeFIkb4VlMOnPwoKDTPAnj8VlMOnPwoKDTPAnj8V8nZavgoKDeFIkb4V8nZavjgCQAFIAFACgAELuAICygITCgdQaW5Ecm9wGggzQ0RCQkM1OQ== \ No newline at end of file diff --git a/tests/fixtures/sharkiq_diagnose_frame.b64 b/tests/fixtures/sharkiq_diagnose_frame.b64 new file mode 100644 index 0000000..923b3b1 --- /dev/null +++ b/tests/fixtures/sharkiq_diagnose_frame.b64 @@ -0,0 +1 @@ +CLuxyQEQSiAGSggIA0BYSABYFFABggEhCgoNvJ9FPhWly1S+GFogACg3MCxYAGAAgAEAiAECmgEAkgLfDyrcD1t7ImtleSI6IkRUX1dBVEVSX1RBTksiLCJ0aW1lIjoiMHMiLCJjb2RlIjoiRFRfQ0FMX0lOSVRJQUxfUE9TRV9TVUNDRVNTIn0seyJrZXkiOiJEVF9XQVRFUl9MRVZFTCIsInRpbWUiOiIwcyIsImNvZGUiOiJEVF9DQUxfSU5JVElBTF9QT1NFX1NVQ0NFU1MifSx7ImtleSI6IkRUX1JFTE9DX1NUQVRFIiwidGltZSI6IjBzIiwiY29kZSI6IlJTX05PTkUifSx7ImtleSI6IkRUX1dFVF9DTEVBTl9NT0RFIiwidGltZSI6IjBzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfU1RBVEVfQ0hBTkdFIiwidGltZSI6IjBzIiwiY29kZSI6IlNZU19TVF9DTEVBTklORyJ9LHsia2V5IjoiRFRfQkFUVEVSWV9WQUxVRV9BVF9TVEFURV9UUkFOUyIsInRpbWUiOiIwcyIsImNvZGUiOiIxMDAifSx7ImtleSI6IkRUX1JFTE9DX1NUQVRFIiwidGltZSI6IjBzIiwiY29kZSI6IlJTX1VOUkVMT0MifSx7ImtleSI6IkRUX0NIQVJHSU5HX1RZUEUiLCJ0aW1lIjoiMHMiLCJjb2RlIjoiQ0hBUkdFX05PTkUifSx7ImtleSI6IkRUX01NX1NUQVRVUyIsInRpbWUiOiIwcyIsImNvZGUiOiJNTV9TVEFUVVNfTE9XTElHSFQifSx7ImtleSI6IkRUX1dBUk5JTkdfQ09ERSIsInRpbWUiOiIwcyIsImNvZGUiOiJXQVJOX01NX0xPV0xJR0hUIn0seyJrZXkiOiJEVF9HT19aT05FX05VTSIsInRpbWUiOiIwcyIsImNvZGUiOiI1In0seyJrZXkiOiJEVF9OT0dPX1pPTkVfTlVNIiwidGltZSI6IjBzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0dPX1pPTkVfRU5BQkxFRF9OVU0iLCJ0aW1lIjoiMHMiLCJjb2RlIjoiMSJ9LHsia2V5IjoiRFRfUkVMT0NfU1RBVEUiLCJ0aW1lIjoiMHMiLCJjb2RlIjoiUlNfUkVMT0MifSx7ImtleSI6IkRUX1JFTE9DX1NUQVRFIiwidGltZSI6IjFzIiwiY29kZSI6IlJTX1VOUkVMT0MifSx7ImtleSI6IkRUX1JFTE9DQUxfU1VDQ0VTUyIsInRpbWUiOiIxcyIsImNvZGUiOiIxIn0seyJrZXkiOiJEVF9SRUxPQ19TVEFURSIsInRpbWUiOiIxcyIsImNvZGUiOiJSU19TVUNDRVNTIn0seyJrZXkiOiJEVF9JTVVfU09GVF9DQUxJX1NVQ0NFU1MiLCJ0aW1lIjoiMnMiLCJjb2RlIjoiMSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTFzIiwiY29kZSI6IkRUX1ZUX0RBUktfVElNRSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTJzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTJzIiwiY29kZSI6IkRUX1ZUX0RBUktfVElNRSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTZzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiNzdzIiwiY29kZSI6IkRUX1ZUX0RBUktfVElNRSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiNzdzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiODRzIiwiY29kZSI6IkRUX1ZUX0RBUktfVElNRSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiODVzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiODhzIiwiY29kZSI6IkRUX1ZUX0RBUktfVElNRSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiODlzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiOTZzIiwiY29kZSI6IkRUX1ZUX0RBUktfVElNRSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiOTdzIiwiY29kZSI6IkRUX0NBTF9JTklUSUFMX1BPU0VfU1VDQ0VTUyJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTAwcyIsImNvZGUiOiJEVF9WVF9EQVJLX1RJTUUifSx7ImtleSI6IkRUX1pfU0lHTkFMIiwidGltZSI6IjEwMHMiLCJjb2RlIjoiRFRfQ0FMX0lOSVRJQUxfUE9TRV9TVUNDRVNTIn1dmAICoAICsAICwAIByAID6AIC \ No newline at end of file diff --git a/tests/fixtures/sharkiq_empty_live_map_frame.b64 b/tests/fixtures/sharkiq_empty_live_map_frame.b64 new file mode 100644 index 0000000..0a2f203 --- /dev/null +++ b/tests/fixtures/sharkiq_empty_live_map_frame.b64 @@ -0,0 +1 @@ +CL+LeBBKIAY6JCABKgUSAIgBAUIHDW8SAzsQAlIHDW8SAzsQAmDmtAJoAKIBAEoICANAS0gAWBRQAYIBBVgAmgEAmAICoAICyAIE6AIC \ No newline at end of file diff --git a/tests/fixtures/sharkiq_live_map_frame.b64 b/tests/fixtures/sharkiq_live_map_frame.b64 new file mode 100644 index 0000000..f122a9f --- /dev/null +++ b/tests/fixtures/sharkiq_live_map_frame.b64 @@ -0,0 +1 @@ +CKmu0QEQSiAGMgIEBDr1uQEgASq/ngENj8J1PRIKDUfhBsEV4Xq0vxi/ASBqMpaeAUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkS2RLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGRkZGRkZGRLD0sPDw8PDw9kZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLZGRkZGRkZGRkZGRkZGRLS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPS0tLS2RkZGRkD2QPDw8PDw9kZEtLSw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGQPS0tLDw8PDw8PD2RkD2RkDw9kS0tLD0sPZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPS0sPDw9kZA8PDw9kZGQPD2RLS0sPSw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PD2QPDw8PDw8PDw8PZGRkZGRkD2RkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD2QPDw8PD2RkZA9kZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PZGRkZA8PDw8PZGRkDw9kZGQPDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PD2RkGQ9kDxkZGRkPDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9LD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLZA8PDw8PDw8PS0tLS0tLS0tLS0tLS0tLS0tLZA9kZA8PDw8KChkZZGQPDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD0tLS0tLS0tLS0tLZGQPDw8ZCg8PDw8PDw8PDw8PDw8PDw9kD2RkD2RkS0tLS0tLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLSw8PDw8PDw8PDw8PDw9kD0tLS2QPZBkPDw8PDw8PDw8PDw8PDw8PDw9kZA8PZGRLS0tLS0tLD2QPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2QPZA8PZA9kDw8PZA8PDw8PDw8PDw8PDw8PDw8PD2QPD2RcXFxcXFxcS0sPZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9WZBkPXGQAZFxcAABcXA9kDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw9kZGQPDw8PDw8PZA8PDw8PDw8PVlZkXFxcAAAAAAAAAAAAD2QPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QPCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9LS2RkZA8PDw8PD0tkZA8PDw9WVgAAAAAAXAAAAAAAAAAAAAAAZA9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw9LS0tLS0tLS0tLS0tLS0tkXFxcXFxcXFxcXFxcXFwPZGRkZGRkZEtkZAoKCgoKCgoKCgoZGQ8PDw8PDw8PDw8PDw8PD2RkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw9kDw8PXFYAAAAAAAAAAAAAAAAAAAAAAABkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PD0tLS0tLS0tkZGRkZGRkZGRkAAAAAAAAAAAAAAAAAGRkZGRkZGRkZGRkCgoKCgoKCgoKCgoZDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDxkZZA8PZGRkXAAAAAAAAAAAAAAAAAAAAAAAAGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PS0tLS0tkS2RkZGRkZGRkDwAAAAAAAAAAAAAAAAAAAA8PD2QPDw8PZGQKCgoKCgoKCgoKChkPDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS2RkZA8PDw8PGWRkDw8PZAAAAAAAAAAAAAAAAAAAAAAAAAAAZA9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD0tLS0tLS2RkZA8PDw9kDw8PAAAAAAAAAAAAAAAAAAAAVg9kZA8PDw8ZZAoKCgoKCgoKCgoKGQ8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9LZGQPDw8PDw8PD2RkDw8AAAAAAAAAAAAAAAAAAAAAAAAAAFxkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PS0tLS2RkDw8PZGQPZGQPDw8AAAAAAAAAAAAAAAAAAABcDw9kDw8PDw9kDwoKCgoKCgoPGRkPDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9kD2QPDw8PD1xkZGRkDwAAAAAAAAAAAAAAAAAAAABcXFwAXGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9LS0tLS0tLSw9kZGRkZA8PDwAAAAAAAAAAAAAAAAAAZFxcZGQPD1xcWWQPCgoKCgoKChkZGQ8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9kZA8PDw9cXGQPXGRkAAAAAAAADw8PAAAAAAAAAFxcXGQPZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9LDw8PD0tLZA8PD2RkD2RkZGRkDw8PDwAAAAAAAAAAAAAAAAAAZGRWXFxcXFoAAAAPCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PD1xkAAAAXGQAAAAAAA8PDwAAAAAAAAAAXA9kZA9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS0tLS0tLD0sPDw8PS0tLZA8PZA8PXFwPZGQPDw8PAAAAAAAAAAAAAAAAAAAAAGRcXFxcXAAAAAAKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPZA8PD2RkZGRcAAAAAAAAXFYAAAAADw8PAAAAAAAAAA9cD2RkDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPSw8PDw9LS0tkS0sPSw8PSw8PDw9LS0tLS1xcXGRkAAAAAAAADw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoKCgoKCgoKDw8KCgoKCgoKDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEsPDw8PZGRkZAAAAAAAAAAAAAAAAAAPDw8AAAAAAABcDw8PZGQPD2RkD0tLS0tkD2RkZGRkZGQPZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRcXFxcXFxcXFxcXFxcZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw9LS2QAAAAAAAAAAAAAAAAAAA8PDwAAAAAAWmRkDw8PZA8PZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD2QPDw8PDw8PZAAAAAAAAAAAAAAAAAAADw8AAAAAVlxkZGRkD2RkD2RkZGRkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw9kAAAAAAAAAAAAAAAAAAAPDwAAAABWXGQPDw8PZGRkZGQPD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkDw8PDw8PD1wAAAAAAAAAAAAAAAAADw8AAAAAAABkZA8PDw9kZGRkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PXAAAAAAAAAAAAAAPDw8PDwAAAAAAAGRkZGRkZGRkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PDw8PDw8PDw9cAAAAAAAADw8PDw8PDw8PAAAAAABcZGRkZGRkZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKCgoPDw8KCgoKCgoKCgoKCgoKCgoKD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9kDw8PDw8PD1xkAAAAAAAPDw8PDw8PDw8AAAAAAFxkZA9kZGRkXGQAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkKCgoKDw8PDw8PDw8PDw8PCgoKCgoKCgoPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2QPDw8PDw8PXAAAAAAAAA8PDw8PDw8PDwAAAAAAXGQPDw9kZGRcZAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxkPDw9kDw8PDw8PDw8PDw8PDwoKCgoKCg9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw9cAAAAAAAADw8PDw8PDw8PAAAAAABcZA8PDw9kZGRkAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PGWRkZGQPDw8PDw8PDw8ZGQoKCgoKD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2RkDw8PDw8PD1wAAAAAAAAPDw8PDw8PDw8AAAAAAFxkXGRkDw9kZGQAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PZA8PD2RkZGRkZGRkZGRkCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZGQPDw8PDw8PXAAAAAAADw8PDw8PDw8PDwAAAAAAAABkXFxcXA9kAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PZGQPDw8PZGRkZGQPDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QPZA8PDw8PD1ZcAAAAAAAPDw8PDw8PDw8PAAAAAAAAAAAAZFxcZGQAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PZA8PDw9kZA8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZA8PDw8PDw8PVlwAAAAAAA8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZA8PZA8PD2QPDw8PD2RkDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PDw8PDw9WXAAAAAAAAA8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw9kDw9kZGQPDw8PZGQPDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tLS0sPD0tcAAAAAAAADw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWg8PDw8PD2QPDw9kDw8PDw8PDw8PZA8PDw8PD2QPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPD1wAAAAAAAAPDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxcXFxcXFxcXFxcXFxcXFxcZGRkZGRkZGRkZGRkZGRkZGRkZGRkZA9kZGRkZGRkD2RkDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PXAAAAAAAAA8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAWlpcXFxcXFxcXFxcXFxcXGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkSw9LZGRkZGRkD2RkDw9kZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9cAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAABcXAAAAAAAAAAAAAAAAFxcXFxcXFxcXFwPDw8PD1xkD2RkZGRkZGRkZGRkS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PZGRLS1wAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZAAAAAAAAAAAAAAAXFxkZGRkZGRkZGRkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PS0tWXAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZBlkZGRkAAAAAAAAAAAAAABcZGRkZGRkZGRkZGRkDw9kD0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPXFxWVlZcAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kD2RkZGQAAAAAAAAAAAAAAABkZABkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZA8AAABaWlwAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QPZGRkXAAAAAAAAAAAAAAAAAAAAABkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9kZGRcZAAAAAAAAAAAAAAAAAAAAFxkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZA8AAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZFxkAAAAAAAAAAAAAAAAAAAAXGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDwAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGQPD2RcAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZA8PZFwAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkDw9kZAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGQPD2RkAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZA9kZGRaAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkD2RcZFwAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPZGRkXAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZA9kZGRkAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kDw8PD2RkZGRkDw9kZGQAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PDw8PDw8PDw8PD2RkZGQAAAAAAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9kZA8PDw8PDw8PDw8PDw8PDw8PZGRkAAAAAAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkAAAAAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQAAAAAAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZAAAAAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkAAAAAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQAAAAAAAAAAAAAAAAAAAAAAFpkZFxcXEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZAAAAAAAAAAAAAAAAAAAAAAAAGRkXFxcXEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkXGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRcZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPXA8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZFxkWQAAAAAAAAAAAAAAAAAAAABcXFxcDw8PZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkXGQAAAAAAAAAAAAAAAAAAFZWXFxcXFwPDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RcZAAAAAAAAAAAAAAAAAAAAFpcZGRkZA8PD2RkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZFxkAAAAAAAAAAAAAAAAAAAAAGRkS0sPZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kXGQAAAAAAAAAAAAAAAAAAAAAZFxcXA8PZGRkZGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RcZAAAAAAAAAAAAAAAAAAAAABkAFkPDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZFxkAAAAAAAAAAAAAAAAAAAAAAAAAF0PDw9kZEsPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kXAAAAAAAAAAAAAAAAAAAAAAAAAAAXV0PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RcAAAAAAAAAAAAAAAAAAAAAAAAAABdDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZFwAAAAAAAAAAAAAAAAAAAAAAAAAXA8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kXGQAAAAAAAAAAABaWloAAABaWloPDw8PDw9kZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9kD2RkZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZA9kXFxcZGRkZGRkZGRkZGRkZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PD2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZA8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PZA8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw8PDw8PDw9kDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PD2QPD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PDw8PDw9kDw8PDw8PDw8PZA8PDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA9kDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw8PDw8PDw9kDw8PDw8PDw9kDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QPDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA9kZGRkZGRkZGQPD2QPD2QPD2QPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLSw8PZGRkZA8PZGRkZGRkZGRkZGRkZGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQPZGQPZA9kZGRLZGRLS0tLS0tLS0sPD0tkZGQPDw9LD0tLDw8PDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD2RkZGRkZGRkZGRkZA8PDw9LD0tLSw8PDw8PS0tLSw8PSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLS0tLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PDw9LDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSgoNTCoLvxXsS7O9iAEBQqIPDW8SAzsQAhqYD8L/0P+i/8//jf/m/5r/YACb/34AmP+8AJn/2gAC/7UAxf6rAKb+qACL/rcAc/7KAFX+zgA5/toA/P3eAN792gC+/dwAYv3gAEP93gCq/N4AbPzfAPH73wCV+98AdvvbADj73QC8+t4AYfrhAEL64ABX+vYAX/oVAYb6RAGu+nIB0PqkAeD6vgHr+toB8vr5Afz6FgL9+jQCHfs4Alr7OQKY+0ACsvtQAsT7aQLN+4UC1vujAtz7wALo+9wC/fvzAgL8EQP++1ADGPznAyr8QgQs/GEEKfx/BBP8lQT5+6UE3fuyBL77tgSg+7AElvvOBJP77gSW+0kFmPtpBZz7iAWW+6UFnPsABpr7HgaX+3sGl/vXBqj77wbH++8G5vvqBkL87Aa+/O4GOf30Blb98AY4/fIGG/3nBgT90wb2/LcG6vybBtf8YAbU/EIG2vwlBuv8CwYx/dAFT/3IBan9wQXH/cEFw/2iBYb9nAVo/aEFS/2ZBTL9iAU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 \ No newline at end of file diff --git a/tests/fixtures/sharkiq_persisted_map_frame.b64 b/tests/fixtures/sharkiq_persisted_map_frame.b64 new file mode 100644 index 0000000..8ff74a2 --- /dev/null +++ b/tests/fixtures/sharkiq_persisted_map_frame.b64 @@ -0,0 +1 @@ +CKHJ1wEQShgBIA0yASs6tdQFCOJ1Egd1bm5hbWVkGggzQ0RCQkM1OSACKpadAQ2PwnU9EgoNR+EGwRXherS/GL8BIGky15wBS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRLZEtLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS0tkZGRkZGRkZGRkZGRkZEtLS0tLZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPZGRkZGRkZGRkZGRkZEtkZGRkS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA9LS0tLZGRkZGQPZA8PDw8PD2RkS0tLS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA9LS0tLDw8PDw8PZGQPZGQPD2RLS0tLSw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA9LS0tLS2RkDw8PD2RkZA8PZEtLS0tLDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw9LS0tLZA8PDw8PDw8PDw9kZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw9LS0sPZA8PDw8PZGRkD2RkZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw9kZGRkDw8PDw9kZGQPDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZGQZD2QPGRkZGQ8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tkDw8PDw8PDw9LS0tLS0tLS0tLS0tLS0tLS0tkD2RkDw8PDwoKGRlkZA8PCgoKCgoKDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0sPDw8PDw8PDw8PDw8PS0tLS0tLS0tLS0tkZA8PDxkKCgoKChkZGQoKCgoKCgoKDw8PZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD2QPS0tLZA9kGQoKCgoKCgoKCgoKCgoKCgoKDw9kDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZA9kDw9kD2QPDw9kCgoKCgoKCgoKCgoKCgoKCgoKGQ8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoZGQ8PZEtLS0tLS0tLS0tLD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkZA8KCgoKCgoKCgoKChkKCgoKCgoKGQ9kZGRkZGRkZGQPDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZA8KCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLZGRkDw8KCgoKCgoKCgoKGQoKCgoKCgoKD2RkDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZGRkZGRkZGRkDw9kZGRkZGRkZGRkCgoKCgoKCgoKChkZDw8PDw8PDw8PDw8PDw8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8KCgoKCgoKChlkCgoKCgoKCgoKDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQKCgoKCgoKCgoKChkPDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PGRlkDw8ZZGRkCgoKCgoKCgoKDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS2RkZGRkZGQPAAAAAAAAAGRkZA8PDw8PDw8PZA8PDw9kZAoKCgoKCgoKCgoKGQ8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLZGRkDw8PDw8ZZGQPDw9kZBkPCgoKCgoKCgoKCgoKDw8PZGQPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PD2QPDwAAAAAAAAAAAAoKCg8PDw8PD2RkDw8PDxlkCgoKCgoKCgoKCgoZDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD0tkZA8PDw8PDw8PZGQPDw9kDw8KCgoKCgoKCgoKCgoKZGRkZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZA9kZA8AAAAAAAAAAAAACgoKCg8PDw8PD2QPDw8PD2QPCgoKCgoKCg8ZGQ8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPD2QPZA8PDw8PDw9kZGQPZGQPDw8KCgoKCgoKCgoKCgpkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkAAAAAAAAAAAAAAAKCgoKCg8PDw9kZA8PD2QPZA8KCgoKCgoKGRkZDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD2RkDw8PDw8PDw8PZGRkZGQPGQ8KCgoKCgoKCgoKCmRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PZGQPZGRkZAAAAAAAAAAAAAAAAAoKCgoKCg8PDw9kZGQPZA8PDw8KCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw9kZGRkZGRkZA8KCgoKCgoKCgoPD2RkS0tLS0tLD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLD0tLS0tLS0tLS0tkDw9kDw8PZFwAAAAAAAAAAAAAAAAKCgoKCgoKCg8PD2RkDxkZDw8PDwoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9kS0sPZGRkZA8PDw8PZGRkZGQPDw8PCgoKCgoKCgoKDw8PZGRLS0tLDw8PDw8PS0tLS0tLS0sPS0tLS0tLS0tLSw8PDw8PZGRkZGRkZGRkDw9LS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAADw8KCgoKCgoKCg8PDw8PDwoKCgoKCgoKCgoKCgoPDwoKCgoKCgoPDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PD0tkZGRkZGQPD2RkDw9kZA8PDwoKCgoKCgoKCgoPDw9kZEtLZGQPD2RkZGRkZGRkZGRkZA9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQPSw9kD0sPS0tLD2RkZGQAAAAAAAAAAAAAAA8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPS0sPDw8PDw9kDw8PDw8PD2RkDw8KCgoKCgoKCgoKCg8PDw9kDw9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkAAAAAAAAAAAAAAAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD0sPDw9LD2QPDw8PDw8PD2QPCgoKCgoKCgoKCgoPDw8PZGQPD2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkCgoKCgAAAAAAAAAAAAAACgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PZGQPDw8PDw8PDwoKCgoKCgoKCgoKDw8PDw9kZGRkZA8PZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoAAAAAAAAAAAAAAAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZA9kZA8PDw8PDw8PCgoKCgoKChkZGRkPDw8PD2RkZGRkZA9kZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgAAAAAAAAAAAAAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw9kDw8PDw8PDwoKCgoKCgoZGWRkZGRkZGRkZGRkD2RkDw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoAAAAAAAAAAAAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PDw8PDw8PZGQPDw8PDw8PCgoKCgoKChlkZGRkZGRkZGRkZGQPD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKAAAAAAAAAAAACgoKCgoKCg8PDw8PDw8PDw8KCgoKCgoKChkPDwoKCgoKCg8PDwoKCgoKCgoKCgoKCgoKCgoPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2QPDw8PDw8PDw8PZGQPDw8PDw8KCgoKCgoKGWRkD2RkD2RkZGRkDw8PD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKAAAAAAAAAAAAAAoKDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKGRkZGQoKCgoPDw8PDw8PDw8PDw8KCgoKCgoKCg9kZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZA8PDw8PDw8PDw9kZA8PDw8PCgoKCgoKCg8PD2QPDw8PD2RkZGRkDw8PD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgAAAAAAAAAAAAAKCg8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoZDw8PGQ8PD2QPDw8PDw8PDw8PDw8PCgoKCgoKD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PD2QKCgoPDwoKCgoKCgoKDw8PZGQPDw8PD2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgAAAAAAAAAAAAAKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKChkPDw8PDw8ZZGRkZA8PDw8PDw8PDxkZCgoKCgoPZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8ZCgoKCgoKCgoKCgoKCgoPDw9kZA9kZGQPD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoAAAAAAAAAAAAACgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKGQ8PDw8PDw9kDw8PZGRkZGRkZGRkZGQKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDxkKCgoKCgoKCgoKCgoKCg8PD2RkZA9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoAAAAAAAAAAAAAAAAAAAoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCg8PDw8PDw8PDw8PDw9kZA8PDw9kZGRkZA8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PZAoKCgoKCgoKCgoKCgoKDw8PD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoAAAAAAAAAAAAAAAAAAAAKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kDw8PD2RkDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PDw9kCgoKCgoKCgoKCgoKCgoKDw8PZGRkZGRkZGQPDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAAAAAAAAAAAAAAAAAAAACgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkDw9kDw8PZA8PDw8PZGQPDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPD2RkCgoKCgoKCg8KCgoKCgoKCg8PZGRkZGRkZA8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgAAAAAAAAAAAAAAAAAAAAoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PDw8PD2QPD2RkZA8PDw9kZA8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tkZGQKCgoKCg8PDwoKCgoKCgoKCg9kZGQPD2QPDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoAAAAAAAAAAAAAAAAAAAAKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PD2QPDw8PDw8PDw9kDw8PDw8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PS2RkZAoKCgoKDw8PDwoKCgoKCgoKCg8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkD2RkZGRkZGQPZGQPDw8PDw9kZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9LZGRkCgoKCgoPDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKGQ8PD2RkCgoAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tkZGRkZGQPZGQPS2RkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZGQKCgoKCg8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PCgoKCgoKCgoKCgoZZGRkZGQPAAAAAAAAAAAAXFxkXA8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRLS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9kZA8PD2RkZAoKCgoKDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDwoKCgoKCgoKCgoKChlkZGRkZAAAAAAAAAAAAABcCmRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoPGWRkZGQAAAAAAAAAAAAAAFxcZGRkZGRkZEtLS0tLS2RLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PZGRkXAAAAAAAAAAAAAAAAFxkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw9kZGRcXAAAAAAAAAAAAAAAAAAAD1xkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PD2RkZFxcAAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw8PZGRkD1wAAAAAAAAAAAAAAAAAAABkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZA8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PD2RkZA8PZAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw8PZGRkDw9kXAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw8PDw9kZGQPD2RcAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw8PDw8PD2RkZA8PZFwAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw8PZGRkD2RkXAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKDw8PDw8PDw8PDw9kZGQPZGRcAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PD2RkZA9kZFwAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw8PZGRkD2RkXFwAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkCgoKCgoKDw8PDw8PDw8PDw9kZGQAAAAAXAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPCgoKCgoPDw8PDw8PDw8PD2RkZAAAAAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZA8KCgoKCg8PDw8PDw8PDw8PZGQAAAAAAAAAAAAAAAoKCgAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8KCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8ZZGQPCgoKCgoKDw8PDw8PDw8PDw9kZGQAAAAAAAAAAAAKCgoKAAAAAABcZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoPDw8PDw8PDw8PD2RkZAAAAAAAAAAACgoKCgoAAAAAAFxkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PZGRkAAAAAAAAAAoKCgoKCgAAAAAAXGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw9kZAAAAAAAAA8KCgoKCgoKAAAAAABcZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8KCgoKCg8PCgoKDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PD2RkAAAAAAAADwoKCgoKCgoAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKDwoKCgoKDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PZGQAAAAAAAAPCgoKCgoKAAAAAAAAZGRcS0tLZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw9kZAAAAAAAAA8KCgoKCgoAAAAAAABkAABkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PD2RkAAAAAAAACgoKCgoKCgAAAAAAAAAAAABcXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQAAAAAAAAKCgoKCgoKAAAAAAAAAAAAAABcZGQPD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZAAAAAAAAAoKCgoKCgoAAAAAAAAAAAAAAFxkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkAAAAAAAACgoKCgoKAAAAAAAAAAAAAAAAD1wPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQAAAAAAAAKCgoKCgAAAAAAAAAAAAAAAAAPDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZAAAAAAAAA8KCgoKAAAAAAAAAAAAAAAAD1xkDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkAAAAAAAADw8KCgoAAAAAAABcZGRkZGQPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QAAAAAAAAPDw8KCgAAAAAAWlxkZGRkZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PGQoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZAAAAAAADw8PDwoKAAAAAAAAZGRkSw9kZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8ZCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kAAAAAAAPDw8PCgoAAAAAAABkZGRLDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDxkKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QAAAAAAAAPAAAAAAAAAAAAAFxcZGRkDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDxkKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZAAAAAAAAAAAAAAAAAAAAAAAAABcDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGQPDw8PDw8PGRkKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZAAAAAAAAAAAAAAAAABaAAAADw8PDw8PD2RkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZFpaWlpaWlpaXGRkZGRkZGRkZGRkZGRkZEtkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PDw9kZGRcDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PDw8PDw8PD2QPDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPDw8PDw8PDw8PDw8PD2QPDw8PDw8PDw9kDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA9kDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kDw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PDw8PDw8PD2QPDw8PDw8PD2RLDw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw9kSw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEsPD2QPDw8PDw8PDw8PDw8PDw8PDw8PD2RLSw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkD2RkZGRkZGRkZA8PZA8PZA8PZA8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLZGRLS2RkZGRkZGRkZGRkZGRkZGRkZGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tLZGRkS0tkZGRkZGRkZGRkZGRkZGQPD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZEtkZGRkS0tLS0tLS2RkZGRkZEtLZEtkZA9kS2RkZEtkZEtLS0tLS0tLS0tLS2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t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V4Xq0vxi/ASBpMtecAUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkS2RLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGRkZGRkS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLZGRkZGRkZGRkZGRkZGRLS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkD2RkZGRkZGRkZGRkZGRLZGRkZEtLZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPS0tLS2RkZGRkD2QPDw8PDw9kZEtLS0tLZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGQPS0tLSw8PDw8PD2RkD2RkDw9kS0tLS0sPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPS0tLS0tkZA8PDw9kZGQPD2RLS0tLSw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PS0tLS2QPDw8PDw8PDw8PZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PS0tLD2QPDw8PD2RkZA9kZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PZGRkZA8PDw8PZGRkDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PD2RkXA9kD1ZWWloPDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLZA8PDw8PDw8PS0tLS0tLS0tLS0tLS0tLS0tLZA9kZA8PDw8AAFpcZGQPDwAAAAAAAA8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD0tLS0tLS0tLS0tLZGQPDw9cAAAAAABaWloAAAAAAAAAAA8PD2RkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLSw8PDw8PDw8PDw8PDw9kD0tLS2QPZFoAAAAAAAAAAAAAAAAAAAAAAA8PZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2QPZA8PZA9kDw8PZAAAAAAAAAAAAAAAAAAAAAAAAFYPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAVlYPD2RLS0tLS0tLS0tLSw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw9kZGQPAAAAAAAAAAAAAABWAAAAAAAAAFYPZGRkZGRkZGRkDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QPAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9LS2RkZA8PAAAAAAAAAAAAAFwAAAAAAAAAAA9kZA8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tkS0tLZGRkS0tLZGRkZGRkZEtkZAAAAAAAAAAAAABcXA8PDw8PDw8PDw8PDw8PD2RkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PAAAAAAAAAABcZAAAAAAAAAAAAA8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkAAAAAAAAAAAAAABcDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PD1xcZA8PXGRkZAAAAAAAAAAAAA8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tkZGRkZGRkD2QPZGQPDw9kZGQPDw8PDw8PD2QPDw8PZGQAAAAAAAAAAAAAAFwPDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS2RkZA8PDw8PXGRkDw8PZGRWDwAAAAAAAAAAAAAAAA8PD2RkDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw9kDw8PDw8PDwAAAAAAAAAPDw8PDw9kZA8PDw9cZAAAAAAAAAAAAAAAXA8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9LZGQPDw8PDw8PD2RkDw8PZA8PAAAAAAAAAAAAAAAAAGRkZGQPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PZGQPZGQPDw8PDw8AAAAAAAAAAAAPDw8PDw9kDw8PDw9kDwAAAAAAAAAPXFwPDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9kD2QPDw8PDw8PZGRkD2RkDw8PAAAAAAAAAAAAAAAAZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRkZA8PDwAAAAAAAAAAAAAAAAAPDw8PZGQPDw9kD2QPAAAAAAAAAFxcXA8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9kZA8PDw8PDw8PD2RkZGRkD1wPAAAAAAAAAAAAAABkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkD2RkZGRkDw8AAAAAAAAAAAAAAAAAAAAPDw8PZGRkD2QPDw8PAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGQPAAAAAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLZA8PZA8PD2QPZGQPDwAAAAAAAAAAAAAAAAAAAAAPDw9kZA9cXA8PDw8AAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPZEtLD2RkZGQPDw8PD2RkZGRkDw8PDwAAAAAAAAAAAA8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRkZA8AAAAAAAAADw8PAAAAAAAAAAAPDw8PDw8AAAAAAAAAAAAAAAAADw8AAAAAAAAADw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEsPDw9LZGRkZGRkDw9kZA8PZGQPDw8AAAAAAAAAAAAADw8PZGRLS2RkD0tLS0tkS2RkZGRkZGQPZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tLZEtLS0tLS0tcXGRkZGQPAAAAAAAAAA8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLDw9LSw8PZA8PDw8PDw9kZA8PAAAAAAAAAAAAAAAPDw8PZEtLZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQPDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw9LDw8PSw9kDw8PDw8PDw9kDwAAAAAAAAAAAAAADw8PD2RkS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD2RkDw8PDw8PDw8AAAAAAAAAAAAAAA8PDw8PZGRkS0tLD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PD2QPZGQPDw8PDw8PDwAAAAAAAABcXFxcDw8PDw9kZGRkZGQPZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PZA8PDw8PDw8AAAAAAAAAXFxkZGRkZGRkZGRkZA9kZA8PZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PDw8PD2RkDw8PDw8PDwAAAAAAAABcZGRkZGRkZGRkZGRkDw9kZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PAAAAAAAAAABWDw8AAAAAAAAPDw8AAAAAAAAAAAAAAAAAAAAAD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PD2RkDw8PDw8PAAAAAAAAAFxkZA9kZA9kZGRkZA8PDw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAFlWVloAAAAADw8PDw8PDw8PDw8PAAAAAAAAAAAPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PZGQPDw8PDwAAAAAAAAAPDw9kDw8PDw9kZGRkZA8PDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAVg8PD1oPDw9kDw8PDw8PDw8PDw8PDwAAAAAAAA9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw9kAAAADw8AAAAAAAAAAA8PD2RkDw8PDw9kZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAABaDw8PDw8PXGRkZGQPDw8PDw8PDw9cXAAAAAAAD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PXAAAAAAAAAAAAAAAAAAADw8PZGQPZGRkDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAFoPDw8PDw8PZA8PD2RkZGRkZGRkZGRkAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw9cAAAAAAAAAAAAAAAAAAAPDw9kZGQPZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAPDw8PDw8PDw8PDw8PZGQPDw8PZGRkZGQPDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PD2QAAAAAAAAAAAAAAAAAAA8PDw9kZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PDw9kZEtLSw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PZAAAAAAAAAAAAAAAAAAAAA8PD2RkZGRkZGRkDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZA8PZA8PD2QPDw8PD2RkS0sPDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9LS0tkZAAAAAAAAAAPAAAAAAAAAAAPD2RkZGRkZGQPDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QPDw8PDw9kDw9kZGQPDw8PZGRLDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLZGRkAAAAAAAPDw8AAAAAAAAAAAAPZGRkDw9kDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QPDw9kDw8PDw8PD0sPZA8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPD0tkZGQAAAAAAA8PDw8AAAAAAAAAAAAPDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZA9kZGRkZGRkD2RkDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PS2RkZAAAAAAADw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFwPDw9cXAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS0tLZGRkZGRkD2RkD0tkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PZGRkAAAAAAAPDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDwAAAAAAAAAAAAAAXGRkZGRkDwAAAAAAAAAAAAAAXA8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PZGQPDw9kZGQAAAAAAA8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8AAAAAAAAAAAAAAABcZGRkZGRkDwAAAAAAAAAAAABkZGRkZGRkZGRkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAD1xkZGRkZGQPDwAAAAAAAAAAXGRkZGRkZGRLS0tLS0tkS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8AAAAAAAAADw8PDw8PD2RkZA9kZGQPDwAAAAAAAA9cZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAA8PDw8PDw8PZGRkDw9kZA8PDwAAAAAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAPDw8PDw8PDw9kZGQPD2RkDw8PAAAAAAAAAAAAAFxkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAADw8PDw8PDw8PD2RkZA8PZA8PDw8AAA8AAAAAAAAAXGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PZGQPDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAA8PDw8PDw8PDw9kZGQPD2QPDw8PDw8AAAAAAAAAAFxkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAPDw8PDw8PDw8PD2RkZA8PZA8PDw8PDwAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAADw8PDw8PDw8PDw8PZGRkDw9kDw8PZGQPDwAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAA8PDw8PDw8PDw8PDw9kZGQPD2QPDw8PZGQPAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAA8PDw8PDw8PDw8PD2RkZA9kZA8PDw8PZA8AAAAAAAAPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAA8PDw8PDw8PDw8PZGRkD2RkDw8PDw9kZAAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAADw8PDw8PDw8PDw9kZGQPZGQPDw8PD1wAAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAPDw8PDw8PDw8PD2RkZA9kZA8PDwAAAAAAAAAAAAAPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZAAAAAAAAA8PDw8PDw8PDw8PZGRkDw9kDw8AAAAAAAAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkDwAAAAAADw8PDw8PDw8PDw9kZGQPDw8PDwAAAAAAAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPAAAAAAAPDw8PDw8PDw8PD2RkZA8PDw8PAAAAAAAAAAAAAA8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PXGRkDwAAAAAAAA8PDw8PDw8PDw8PZGRkDw8PDw8AAAAAAAAAAAAPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8AAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAADw8PDw8PDw8PDw9kZGRkDw8PDwAAAAAAAAAAAA8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDwAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PD2RkZA8PDw8PDwAAAAAAAAAADw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PZGRkDw8PDw8PAAAAAAAAAAAPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PAAAAAAAPDwAAAA8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw9kZGQPDw8PDw8AAAAAAAAADw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8AAAAAAA8AAAAAAA8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PD2RkZA8PDw8PDwAAAAAAAAAPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PAAAAAAAAAA8PDw8PZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDwAAAAAAAAAADw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8AAAAAAAAAAAAPDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDwAAAAAAAAAAAA8PDw8PDw8PDw8PZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PAAAAAAAAAAAADw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8AAAAAAAAAAA8PDwAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PAAAAAAAAAAAPDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PAAAAAAAAAA8PDw8PDw8PDw8PZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkDw8PDw8PAAAAAAAADw8PD2RkZGRkDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PAAAAAAAADw8PZGRkZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD1YAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkDw8PDw8PDw8AAAAAAAAAD2RkZEtLZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PVgAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPDw8PDw8PDwAAAAAAAAAAXGRkSw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw9ZAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PAAAAAAAAAAAAVmRkZA8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw9aAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PAAAAAAAAAAAPDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw8PD1laAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PAAAAAAAAAA8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw8AAAAAAAAPDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkDw8PDw8PDw8PDw8PDw9kZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZEtkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZEsPDw8PDw8PDw8PZGRkDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLSw8PDw8PDw8PDw8PDw9kDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLDw8PDw8PDw8PD2RkZA8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkSw8PDw8PDw8PDw8PDw9kDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtkDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLSw8PDw8PDw8PDw8PDw9kDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEsPDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtkZGRkZGRkZGQPD2QPD2QPD2QPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS2RkS0tkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tLS2RkZEtLZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGRkZGRkZGRLZGRkZEtLS0tLS0tkZGRkZGRLS2RLZGQPZEtkZGRLZGRLS0tLS0tLS0tLS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0ABSg8NfHTsvhX108G8HYadGT1VAACAP1jjEhr9Nxj///////////8BIP///////////wEoATLiN1t7ImtleSI6IkRUX1ZFUlNJT05fTUNVIiwidGltZSI6IjBzIiwiY29kZSI6IkxpZGFyMl8wTTEuMC45MSJ9LHsia2V5IjoiRFRfVkVSU0lPTl9MMDEiLCJ0aW1lIjoiMHMiLCJjb2RlIjoiVjYuNi4xMC1QNy5OMzMwOC4xNy4wLVNlcCAyMSAyMDIzIn0seyJrZXkiOiJEVF9XQVRFUl9UQU5LIiwidGltZSI6IjE3ODk4NjUzODNzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX1dBVEVSX0xFVkVMIiwidGltZSI6IjE3ODk4NjUzODNzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX1JFTE9DX1NUQVRFIiwidGltZSI6IjE3ODk4NjUzODNzIiwiY29kZSI6IlJTX05PTkUifSx7ImtleSI6IkRUX0dPX1pPTkVfSU5GTyIsInRpbWUiOiIxNzg5ODY3MDA2cyIsImNvZGUiOiJJbmZvOltab25lXUdldCBSb29tIERlZmluZTogPDNDREJCQzU5PjxHb1pvbmU6QmF0aHJvb20uICxSb29tLExhdW5kcnkgUm9vbSxIYWxsd2F5LD48Tm9Hb1pvbmU6PntIYTFhaGt3eTJRSWFDRE5EUkVKQ1F6VTVlbGNTQ2tKaGRHaHliMjl0TGlBYUNrSmhkR2h5YjI5dExpQWlNQW9LRFErb0hzQVZxN3AxUUFvS0RWcHkycjRWcTdwMVFBb0tEVnB5MnI0Vjh2eTJQd29LRFErb0hzQVZBZjIyUDRJQkNrSmhkR2h5YjI5dExpQjZSUklFVW05dmJSb0VVbTl2YlNJd0Nnb05KSWpmd0JVZk9KSkFDZ29OWDc4bndCVWZPSkpBQ2dvTlg3OG53Qlg5RFpTL0Nnb05KSWpmd0JYOURaUy9nZ0VFVW05dmJYcGRFZ3hNWVhWdVpISjVJRkp2YjIwYURFeGhkVzVrY25rZ1VtOXZiU0l3Q2dvTmxxaDZQeFdjd2VRL0Nnb044UytRUUJXY3dlUS9DZ29OOFMrUVFCVUxxdDYvQ2dvTmxxaDZQeFVMcXQ2L2dnRU1UR0YxYm1SeWVTQlNiMjl0ZWs0U0IwaGhiR3gzWVhrYUIwaGhiR3gzWVhraU1Bb0tEYWpTSzhBVkk5NjRQd29LRFk1cmZqOFZJOTY0UHdvS0RZNXJmajhWYW5RQ3dBb0tEYWpTSzhBVmFuUUN3SUlCQjBoaGJHeDNZWGxDQWxnVVNBR1NBZ1FvQWpBQ3FnSWRDR1FRQUJnQUtBQXdBRGdEUVAvLy8vLy8vLy8vL3dGUUFtQUVhQUs0QWdJPX0ifSx7ImtleSI6IkRUX0dPX1pPTkVfSU5GTyIsInRpbWUiOiIxNzg5ODY3MDA3cyIsImNvZGUiOiJJbmZvOltab25lXUdldCBSb29tIERlZmluZTogPDNDREJCQzU5PjxHb1pvbmU6QmF0aHJvb20uICxSb29tLExhdW5kcnkgUm9vbSxIYWxsd2F5LD48Tm9Hb1pvbmU6PntIY1phaGt3eXJBSWFDRE5EUkVKQ1F6VTVla29TQ2tKaGRHaHliMjl0TGlBYUNrSmhkR2h5YjI5dExpQWlNQW9LRFErb0hzQVZxN3AxUUFvS0RWcHkycjRWcTdwMVFBb0tEVnB5MnI0Vjh2eTJQd29LRFErb0hzQVZBZjIyUDNvK0VnUlNiMjl0R2dSU2IyOXRJakFLQ2cwa2lOL0FGUjg0a2tBS0NnMWZ2eWZBRlI4NGtrQUtDZzFmdnlmQUZmME5sTDhLQ2cwa2lOL0FGZjBObEw5NlRoSU1UR0YxYm1SeWVTQlNiMjl0R2d4TVlYVnVaSEo1SUZKdmIyMGlNQW9LRFphb2VqOFZuTUhrUHdvS0RmRXZrRUFWbk1Ia1B3b0tEZkV2a0VBVkM2cmV2d29LRFphb2VqOFZDNnJldjNwRUVnZElZV3hzZDJGNUdnZElZV3hzZDJGNUlqQUtDZzJvMGl2QUZTUGV1RDhLQ2cyT2EzNC9GU1BldUQ4S0NnMk9hMzQvRldwMEFzQUtDZzJvMGl2QUZXcDBBc0JDQWxnVVNBR0FBUXVTQWdRb0FqQUNxZ0lkQ0dRUUFCZ0FLQUF3QURnRFFQLy8vLy8vLy8vLy93RlFBbUFFYUFLNEFnTEtBaFlLQ2tKaGRHaHliMjl0TGlBYUNETkRSRUpDUXpVNX0ifSx7ImtleSI6IkRUX0dPX1pPTkVfSU5GTyIsInRpbWUiOiIxNzg5ODY3MDA3cyIsImNvZGUiOiJJbmZvOltHb1pvbmVdIGdldCBVU1JfQ1RSX0FVVE8sPDNDREJCQzU5PjxHb3pvbmVzOkJhdGhyb29tLiAsPntIY1phaGt3eXJBSWFDRE5EUkVKQ1F6VTVla29TQ2tKaGRHaHliMjl0TGlBYUNrSmhkR2h5YjI5dExpQWlNQW9LRFErb0hzQVZxN3AxUUFvS0RWcHkycjRWcTdwMVFBb0tEVnB5MnI0Vjh2eTJQd29LRFErb0hzQVZBZjIyUDNvK0VnUlNiMjl0R2dSU2IyOXRJakFLQ2cwa2lOL0FGUjg0a2tBS0NnMWZ2eWZBRlI4NGtrQUtDZzFmdnlmQUZmME5sTDhLQ2cwa2lOL0FGZjBObEw5NlRoSU1UR0YxYm1SeWVTQlNiMjl0R2d4TVlYVnVaSEo1SUZKdmIyMGlNQW9LRFphb2VqOFZuTUhrUHdvS0RmRXZrRUFWbk1Ia1B3b0tEZkV2a0VBVkM2cmV2d29LRFphb2VqOFZDNnJldjNwRUVnZElZV3hzZDJGNUdnZElZV3hzZDJGNUlqQUtDZzJvMGl2QUZTUGV1RDhLQ2cyT2EzNC9GU1BldUQ4S0NnMk9hMzQvRldwMEFzQUtDZzJvMGl2QUZXcDBBc0JDQWxnVVNBR0FBUXVTQWdRb0FqQUNxZ0lkQ0dRUUFCZ0FLQUF3QURnRFFQLy8vLy8vLy8vLy93RlFBbUFFYUFLNEFnTEtBaFlLQ2tKaGRHaHliMjl0TGlBYUNETkRSRUpDUXpVNX0ifSx7ImtleSI6IkRUX1dFVF9DTEVBTl9NT0RFIiwidGltZSI6IjE3ODk4NjcwMDdzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX1NUQVRFX0NIQU5HRSIsInRpbWUiOiIxNzg5ODY3MDA3cyIsImNvZGUiOiJTWVNfU1RfQ0xFQU5JTkcifSx7ImtleSI6IkRUX0JBVFRFUllfVkFMVUVfQVRfU1RBVEVfVFJBTlMiLCJ0aW1lIjoiMTc4OTg2NzAwN3MiLCJjb2RlIjoiMTAwIn0seyJrZXkiOiJEVF9SRUxPQ19TVEFURSIsInRpbWUiOiIxNzg5ODY3MDA3cyIsImNvZGUiOiJSU19VTlJFTE9DIn0seyJrZXkiOiJEVF9MSURBUl9TQ0FORlJFUVVFTkNZX1ZBTFVFIiwidGltZSI6IjE3ODk4NjcwMDdzIiwiY29kZSI6IlJlc2V0IExpZGFyIFNjYW5GcmVxdWVuY3k6IDYuMCJ9LHsia2V5IjoiRFRfQ0hBUkdJTkdfVFlQRSIsInRpbWUiOiIxNzg5ODY3MDA3cyIsImNvZGUiOiJDSEFSR0VfTk9ORSJ9LHsia2V5IjoiRFRfTU1fU1RBVFVTIiwidGltZSI6IjE3ODk4NjcwMDhzIiwiY29kZSI6Ik1NX1NUQVRVU19MT1dMSUdIVCJ9LHsia2V5IjoiRFRfV0FSTklOR19DT0RFIiwidGltZSI6IjE3ODk4NjcwMDhzIiwiY29kZSI6IldBUk5fTU1fTE9XTElHSFQifSx7ImtleSI6IkRUX0dPX1pPTkVfSU5GTyIsInRpbWUiOiIxNzg5ODY3MDExcyIsImNvZGUiOiJJTkZPOiBbWm9uZUluZm9dIEdvIHpvbmUgQmF0aHJvb20uICBpcyBlbmFibGVkISJ9LHsia2V5IjoiRFRfR09fWk9ORV9JTkZPIiwidGltZSI6IjE3ODk4NjcwMTFzIiwiY29kZSI6IklORk86IFtab25lSW5mb10gR28gem9uZSBSb29tIGlzIG5vdCBlbmFibGVkISJ9LHsia2V5IjoiRFRfR09fWk9ORV9JTkZPIiwidGltZSI6IjE3ODk4NjcwMTFzIiwiY29kZSI6IklORk86IFtab25lSW5mb10gR28gem9uZSBMYXVuZHJ5IFJvb20gaXMgbm90IGVuYWJsZWQhIn0seyJrZXkiOiJEVF9HT19aT05FX0lORk8iLCJ0aW1lIjoiMTc4OTg2NzAxMXMiLCJjb2RlIjoiSU5GTzogW1pvbmVJbmZvXSBHbyB6b25lIEhhbGx3YXkgaXMgbm90IGVuYWJsZWQhIn0seyJrZXkiOiJEVF9HT19aT05FX05VTSIsInRpbWUiOiIxNzg5ODY3MDExcyIsImNvZGUiOiI0In0seyJrZXkiOiJEVF9OT0dPX1pPTkVfTlVNIiwidGltZSI6IjE3ODk4NjcwMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0dPX1pPTkVfRU5BQkxFRF9OVU0iLCJ0aW1lIjoiMTc4OTg2NzAxMXMiLCJjb2RlIjoiMSJ9LHsia2V5IjoiRFRfUkVMT0NfU1RBVEUiLCJ0aW1lIjoiMTc4OTg2NzAxMnMiLCJjb2RlIjoiUlNfUkVMT0MifSx7ImtleSI6IkRUX1NQRUNJQUxfTU9ERSIsInRpbWUiOiIxNzg5ODY3MDEycyIsImNvZGUiOiJDdXJyZW50IHNwZWNpYWwgbW9kZTogVU5ERUZJTkVEX01PREUifSx7ImtleSI6IkRUX1JFTE9DX1NUQVRFIiwidGltZSI6IjE3ODk4NjcwMTNzIiwiY29kZSI6IlJTX1VOUkVMT0MifSx7ImtleSI6IkRUX1JFTE9DQUxfU1VDQ0VTUyIsInRpbWUiOiIxNzg5ODY3MDEzcyIsImNvZGUiOiIxIn0seyJrZXkiOiJEVF9SRUxPQ19TVEFURSIsInRpbWUiOiIxNzg5ODY3MDEzcyIsImNvZGUiOiJSU19TVUNDRVNTIn0seyJrZXkiOiJEVF9JTVVfU09GVF9DQUxJX1NVQ0NFU1MiLCJ0aW1lIjoiMXMiLCJjb2RlIjoiMSJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTBzIiwiY29kZSI6IjE1In0seyJrZXkiOiJEVF9QUF9SRUxPQ19TVEFUVVMiLCJ0aW1lIjoiMTRzIiwiY29kZSI6IlJlbG9jIHN1Y2Nlc3MifSx7ImtleSI6IkRUX0NMRUFOSU5HX01PREUiLCJ0aW1lIjoiMTVzIiwiY29kZSI6IkNsZWFuaW5nIG1vZGU6IFJPT01fU0VMRUNUSU9OIn0seyJrZXkiOiJEVF9SRUxPQ19NT0RFIiwidGltZSI6IjE1cyIsImNvZGUiOiJSZWxvY2F0aW9uIG1vZGU6IFNQSU4ifSx7ImtleSI6IkRUX1NQRUNJQUxfTU9ERSIsInRpbWUiOiIxNXMiLCJjb2RlIjoiQ3VycmVudCBzcGVjaWFsIG1vZGU6IFVOREVGSU5FRF9NT0RFIn0seyJrZXkiOiJEVF9aX1NJR05BTCIsInRpbWUiOiIxOXMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfV0ZGX1RFUk1fQ09ERSIsInRpbWUiOiIxMDFzIiwiY29kZSI6IlpvbmU6IDEsIE5PUk1BTCJ9LHsia2V5IjoiRFRfRE9DS19DT0RFIiwidGltZSI6IjEyOXMiLCJjb2RlIjoiREVfVVNSX0NUUl9ET0NLIn0seyJrZXkiOiJEVF9TVEFURV9DSEFOR0UiLCJ0aW1lIjoiMTI5cyIsImNvZGUiOiJTWVNfU1RfRE9DS0lORyJ9LHsia2V5IjoiRFRfQkFUVEVSWV9WQUxVRV9BVF9TVEFURV9UUkFOUyIsInRpbWUiOiIxMjlzIiwiY29kZSI6Ijk0In0seyJrZXkiOiJEVF9MSURBUl9TQ0FORlJFUVVFTkNZX1ZBTFVFIiwidGltZSI6IjEyOXMiLCJjb2RlIjoiUmVzZXQgTGlkYXIgU2NhbkZyZXF1ZW5jeTogNC41In0seyJrZXkiOiJEVF9aX1NJR05BTCIsInRpbWUiOiIxNTRzIiwiY29kZSI6IjE1In0seyJrZXkiOiJEVF9aX1NJR05BTCIsInRpbWUiOiIxNTVzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX1pfU0lHTkFMIiwidGltZSI6IjE1NXMiLCJjb2RlIjoiMTUifSx7ImtleSI6IkRUX1pfU0lHTkFMIiwidGltZSI6IjE1NnMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfWl9TSUdOQUwiLCJ0aW1lIjoiMTU2cyIsImNvZGUiOiIxNSJ9LHsia2V5IjoiRFRfVElNRV9QUF9ET0NLIiwidGltZSI6IjE1N3MiLCJjb2RlIjoiMjcifSx7ImtleSI6IkRUX0ZBU1RfRE9DS0lORyIsInRpbWUiOiIxNThzIiwiY29kZSI6IjEifSx7ImtleSI6IkRUX0JBUkNPREVfU0laRSIsInRpbWUiOiIxNThzIiwiY29kZSI6IjI3In0seyJrZXkiOiJEVF9aX1NJR05BTCIsInRpbWUiOiIxNjJzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX1pfU0lHTkFMIiwidGltZSI6IjE2MnMiLCJjb2RlIjoiMTUifSx7ImtleSI6IkRUX1pfU0lHTkFMIiwidGltZSI6IjE2NHMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfVElNRV9CQVNFX0RPQ0siLCJ0aW1lIjoiMTcycyIsImNvZGUiOiIxNCJ9LHsia2V5IjoiRFRfQUVEX0hBVENIRE9PUl9PUEVOX1RJTUUiLCJ0aW1lIjoiMjEwcyIsImNvZGUiOiIxNjA1MCJ9LHsia2V5IjoiRFRfQUVEX0hBVENIRE9PUl9DTE9TRV9USU1FIiwidGltZSI6IjIxMHMiLCJjb2RlIjoiMTAxMTkifSx7ImtleSI6IkRUX0NIQVJHSU5HX1RZUEUiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiJDSEFSR0VfQkFDSyJ9LHsia2V5IjoiRFRfU1RBVEVfQ0hBTkdFIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiU1lTX1NUX1dBSVRJTkcifSx7ImtleSI6IkRUX0JBVFRFUllfVkFMVUVfQVRfU1RBVEVfVFJBTlMiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiI5NCJ9LHsia2V5IjoiRFRfTk9STUFMX0NMRUFOX1RJTUUiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIyOCJ9LHsia2V5IjoiRFRfRk9MTE9XX0NMRUFOX1RJTUUiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiI3MyJ9LHsia2V5IjoiRFRfRVNDQVBFX0NMRUFOX1RJTUUiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIwIn0seyJrZXkiOiJEVF9OT1JNQUxfRE9DS19USU1FIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMjcifSx7ImtleSI6IkRUX0ZPTExPV19ET0NLX1RJTUUiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIwIn0seyJrZXkiOiJEVF9FU0NBUEVfRE9DS19USU1FIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfU1RBUlRfRlJPTV9ET0NLIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMSJ9LHsia2V5IjoiRFRfQ0xJRkZfUklHSFRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0NMSUZGX0NFTlRFUl9SSUdIVF9DT1VOVEVSIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfQ0xJRkZfQ0VOVEVSX0xFRlRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0NMSUZGX0xFRlRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0JVTVBFUl9UT1BfUklHSFRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0JVTVBFUl9UT1BfQ0VOVEVSX0NPVU5URVIiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIwIn0seyJrZXkiOiJEVF9CVU1QRVJfVE9QX0xFRlRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0JVTVBFUl9MSURBUl9SSUdIVF9DT1VOVEVSIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfQlVNUEVSX0xJREFSX0NFTlRFUl9DT1VOVEVSIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfQlVNUEVSX0xJREFSX0xFRlRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjAifSx7ImtleSI6IkRUX0JVTVBFUl9SSUdIVF9DT1VOVEVSIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMiJ9LHsia2V5IjoiRFRfQlVNUEVSX0xFRlRfQ09VTlRFUiIsInRpbWUiOiIyMTFzIiwiY29kZSI6IjUifSx7ImtleSI6IkRUX0JVTVBFUl9CT1RIX0NPVU5URVIiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIxIn0seyJrZXkiOiJEVF9JUl9BVk9JRF9SSUdIVF9DT1VOVEVSIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMCJ9LHsia2V5IjoiRFRfSVJfQVZPSURfQ0VOVEVSX0NPVU5URVIiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIwIn0seyJrZXkiOiJEVF9JUl9BVk9JRF9MRUZUX0NPVU5URVIiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiIwIn0seyJrZXkiOiJEVF9NTV9TVEFUVVMiLCJ0aW1lIjoiMjExcyIsImNvZGUiOiJNTV9TVEFUVVNfTE9XTElHSFQifSx7ImtleSI6IkRUX1BFUlNJU1RfVkFMIiwidGltZSI6IjIxMXMiLCJjb2RlIjoiMTAwIn0seyJrZXkiOiJEVF9DVVJSRU5UX1VUQ19USU1FIiwidGltZSI6IjBzIiwiY29kZSI6IlN1biBTZXAgMjAgMDE6MjA6MjQgVVRDIDIwMjYifV2qAe25Ag2PwnU9EgoNR+EGwRXherS/GL8BIGky15wBS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRLZEtLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS0tkZGRkZGRkZGRkZGRkZEtLS0tLZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPZGRkZGRkZGRkZGRkZEtkZGRkS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA9LS0tLZGRkZGQPZA8PDw8PD2RkS0tLS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA9LS0tLDw8PDw8PZGQPZGQPD2RLS0tLSw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA9LS0tLS2RkDw8PD2RkZA8PZEtLS0tLDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw9LS0tLZA8PDw8PDw8PDw9kZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw9LS0sPZA8PDw8PZGRkD2RkZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw9kZGRkDw8PDw9kZGQPDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZGRcD2QPVlZaWg8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tkDw8PDw8PDw9LS0tLS0tLS0tLS0tLS0tLS0tkD2RkDw8PDwoKWlxkZA8PCgoKCgoKDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0sPDw8PDw8PDw8PDw8PS0tLS0tLS0tLS0tkZA8PD1wKCgoKClpaWgoKCgoKCgoKDw8PZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD2QPS0tLZA9kWgoKCgoKCgoKCgoKCgoKCgoKDw9kDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZA9kDw9kD2QPDw9kCgoKCgoKCgoKCgoKCgoKCgoKVg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgpWVg8PZEtLS0tLS0tLS0tLD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkZA8KCgoKCgoKCgoKClYKCgoKCgoKVg9kZGRkZGRkZGQPDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZA8KCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLZGRkDw8KCgoKCgoKCgoKXAoKCgoKCgoKD2RkDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS2RLS0tkZGRLS0tkZGRkZGRkS2RkCgoKCgoKCgoKClxcDw8PDw8PDw8PDw8PDw8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8KCgoKCgoKClxkCgoKCgoKCgoKDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQKCgoKCgoKCgoKClwPDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PXFxkDw9cZGRkCgoKCgoKCgoKDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS2RkZGRkZGQPZA9kZA8PD2RkZA8PDw8PDw8PZA8PDw9kZAoKCgoKCgoKCgoKXA8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLZGRkDw8PDw9cZGQPDw9kZFYPCgoKCgoKCgoKCgoKDw8PZGQPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PD2QPDw8PDw8PCgoKCgoKCg8PDw8PD2RkDw8PD1xkCgoKCgoKCgoKCgpcDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD0tkZA8PDw8PDw8PZGQPDw9kDw8KCgoKCgoKCgoKCgoKZGRkZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZA9kZA8PDw8PDwoKCgoKCgoKCg8PDw8PD2QPDw8PD2QPCgoKCgoKCg9cXA8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPD2QPZA8PDw8PDw9kZGQPZGQPDw8KCgoKCgoKCgoKCgpkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkDw8PCgoKCgoKCgoKCgoKCg8PDw9kZA8PD2QPZA8KCgoKCgoKXFxcDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD2RkDw8PDw8PDw8PZGRkZGQPXA8KCgoKCgoKCgoKCmRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PZGQPZGRkZGQPDwoKCgoKCgoKCgoKCgoKCg8PDw9kZGQPZA8PDw8KCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw9kZGRkZGRkZA8KCgoKCgoKCgoPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tkDw9kDw8PZA9kZA8PCgoKCgoKCgoKCgoKCgoKCg8PD2RkD1xcDw8PDwoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9kS0sPZGRkZA8PDw8PZGRkZGQPDw8PCgoKCgoKCgoKDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkDwoKCgoKCgoPDw8KCgoKCgoKCg8PDw8PDwoKCgoKCgoKCgoKCgoPDwoKCgoKCgoPDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkSw8PD0tkZGRkZGQPD2RkDw9kZA8PDwoKCgoKCgoKCgoPDw9kZEtLZGQPS0tLS2RLZGRkZGRkZA9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tkS0tLS0tLS1xcZGRkZA8KCgoKCgoKDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPS0sPD0tLDw9kDw8PDw8PD2RkDw8KCgoKCgoKCgoKCg8PDw9kS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZA8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD0sPDw9LD2QPDw8PDw8PD2QPCgoKCgoKCgoKCgoPDw8PZGRLS2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PZGQPDw8PDw8PDwoKCgoKCgoKCgoKDw8PDw9kZGRLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZA9kZA8PDw8PDw8PCgoKCgoKClxcXFwPDw8PD2RkZGRkZA9kZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw9kDw8PDw8PDwoKCgoKCgpcXGRkZGRkZGRkZGRkD2RkDw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PDw8PZGQPDw8PDw8PCgoKCgoKClxkZGRkZGRkZGRkZGQPD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8KCgoKCgoKClYPDwoKCgoKCg8PDwoKCgoKCgoKCgoKCgoKCgoPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PZGQPDw8PDw8KCgoKCgoKXGRkD2RkD2RkZGRkDw8PD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKWVZWWgoKCgoPDw8PDw8PDw8PDw8KCgoKCgoKCg9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw9kZA8PDw8PCgoKCgoKCg8PD2QPDw8PD2RkZGRkDw8PD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgpWDw8PWg8PD2QPDw8PDw8PDw8PDw8PCgoKCgoKD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PD2QKCgoPDwoKCgoKCgoKDw8PZGQPDw8PD2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCloPDw8PDw9cZGRkZA8PDw8PDw8PD1xcCgoKCgoPZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw9cCgoKCgoKCgoKCgoKCgoPDw9kZA9kZGQPD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKWg8PDw8PDw9kDw8PZGRkZGRkZGRkZGQKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD1wKCgoKCgoKCgoKCgoKCg8PD2RkZA9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCg8PDw8PDw8PDw8PDw9kZA8PDw9kZGRkZA8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PZAoKCgoKCgoKCgoKCgoKDw8PD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kDw8PD2RkS0tLDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PDw9kCgoKCgoKCgoKCgoKCgoKDw8PZGRkZGRkZGQPDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkDw9kDw8PZA8PDw8PZGRLSw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLS2RkCgoKCgoKCg8KCgoKCgoKCg8PZGRkZGRkZA8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PDw8PD2QPD2RkZA8PDw9kZEsPDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tkZGQKCgoKCg8PDwoKCgoKCgoKCg9kZGQPD2QPDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PD2QPDw8PDw8PSw9kDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PS2RkZAoKCgoKDw8PDwoKCgoKCgoKCg8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkD2RkZGRkZGQPZGQPDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9LZGRkCgoKCgoPDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKXA8PD1xcCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tkZGRkZGQPZGQPS2RkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZGQKCgoKCg8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PCgoKCgoKCgoKCgpcZGRkZGQPCgoKCgoKCgoKCgpcDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRLS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9kZA8PD2RkZAoKCgoKDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDwoKCgoKCgoKCgoKClxkZGRkZGQPCgoKCgoKCgoKCmRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoPXGRkZGRkZA8PCgoKCgoKCgpcZGRkZGRkZEtLS0tLS2RLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PZGRkD2RkZA8PCgoKCgoKD1xkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw9kZGQPD2RkDw8PCgoKCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PD2RkZA8PZGQPDw8KCgoKCgoKCgoKXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw8PZGRkDw9kDw8PDwoKDwoKCgoKCgpcZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZA8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PD2RkZA8PZA8PDw8PDwoKCgoKCgoKXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw8PZGRkDw9kDw8PDw8PCgoKCgoKCgpcZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw8PDw9kZGQPD2QPDw9kZA8PCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw8PDw8PD2RkZA8PZA8PDw9kZA8KCgoKCgoPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw8PZGRkD2RkDw8PDw9kDwoKCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKDw8PDw8PDw8PDw9kZGQPZGQPDw8PD2RkCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PD2RkZA9kZA8PDw8PXAoKCgoKCgoPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw8PZGRkD2RkDw8PCgoKCgoKCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkCgoKCgoKDw8PDw8PDw8PDw9kZGQPD2QPDwoKCgoKCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPCgoKCgoPDw8PDw8PDw8PD2RkZA8PDw8PCgoKCgoKCgoKCgoPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZA8KCgoKCg8PDw8PDw8PDw8PZGRkDw8PDw8KCgoKCgoKCgoKDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8KCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9cZGQPCgoKCgoKDw8PDw8PDw8PDw9kZGQPDw8PDwoKCgoKCgoKCg8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoPDw8PDw8PDw8PD2RkZGQPDw8PCgoKCgoKCgoKDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PZGRkDw8PDw8PCgoKCgoKCgoPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw9kZGQPDw8PDw8KCgoKCgoKCg8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8KCgoKCg8PCgoKDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PD2RkZA8PDw8PDwoKCgoKCgoPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKDwoKCgoKDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PZGRkDw8PDw8PCgoKCgoKCg8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8KCgoKCgoKDw8PDw9kZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDwoKCgoKCgoKCg8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PCgoKCgoKCgoKDw8PDw8PDw8PDw9kZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8KCgoKCgoKCgoPDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8KCgoKCgoKDw8PDw8PDw8PDw9kDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPDw8PDw8KCgoKCgoPDw8PZGRkZGQPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkDw8PDw8PDw8KCgoKCgoPDw9kZGRkZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PVgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPDw8PDw8PDwoKCgoKCgoPZGRkS0tkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw9WCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PCgoKCgoKCgpcZGRLDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PD1kKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8KCgoKCgoKCgpWZGRkDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PD1oKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGQPDw8PDw8PWVoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PDwoKCgoKCg8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGQPDw8PDw8PDw8PDw8PD2RkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZEtkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkSw8PDw8PDw8PDw9kZGQPDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLDw8PDw8PDw8PDw8PD2QPDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0sPDw8PDw8PDw8PZGRkDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLDw8PDw8PDw8PDw8PD2QPDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtkDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLDw8PDw8PDw8PDw8PD2QPDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkSw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEsPD2QPDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2RkZGRkZGRkZA8PZA8PZA8PZA8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLZGRLS2RkZGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tLZGRkS0tkZGRkZGRkZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZEtkZGRkS0tLS0tLS2RkZGRkZEtLZEtkZA9kS2RkZEtkZEtLS0tLS0tLS0tLS2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLPQAAyEJAAUoPDXx07L4V9dPBvB2GnRk9VQAAgD9Y4xKaAdecAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAABAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQABAQEBAQEBAQEAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEAAAEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMAAAADAwMDAwMAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEAAAEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAACAgIAAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAACAgICAgICAgIAAAICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQADAwMAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAwMDAwMDAwMDAwMDAAMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAADAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAADAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAADAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAwMDAAADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAMDAwMDAAMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAwMDAwMAAAMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAADAwMDAwADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAADAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAADAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAAAAAAMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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 \ No newline at end of file diff --git a/tests/fixtures/sharkiq_requested_map_frame.b64 b/tests/fixtures/sharkiq_requested_map_frame.b64 new file mode 100644 index 0000000..55b4f3a --- /dev/null +++ b/tests/fixtures/sharkiq_requested_map_frame.b64 @@ -0,0 +1 @@ +CNrkZBBKIA461/UFCLfXAxIHdW5uYW1lZBoIM0NEQkJDNTkgBCq/ogENj8J1PRIKDUfhBsEVHoXLvxjAASBsMoCiAUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPDw9kZGRkZGRLS0tLD0sPDw8PD2RkZA9kDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD0tLS0tLD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkD2RkZGRkDw8PDw9kZGRkZGRkZGRkZGQPDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLDw9kZGRkZGRkZA9kZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkD2RkDw8PDw8PDw8PDw8PD2QPDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PD2RkZGRkZGRkZGQPZA8PS0tLSw8PDw8PS0tLS0tLS0tLDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGRkZGRkXGRkZGRcXFxcXFxcXFxcXFwPZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEsPDw8PD2RkZGRkZGRkZGRkZGRkS0tLSw9kZA8PS0sPS0tLS0tLD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAGRkZGRkZGRkZGRkXGRkZAAAAABkZFxcZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PZGRkZGQPZA8PDw8PD2RkS0tLSw9kZGRLS0sPS0tLS0tLD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGQPDw8PZA8PDw8PD2RkD2RkDw9kD0sPDw8PZGRLSw8PS0tLS0sPDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWmQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PD2QPZGQPDw8PZGRkDw9kZGRkZGQPD2RLSw8PS0tLS0tLDw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPS0tLDw9LS0tLS0tLD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PZA8PDw8PDw8PDw9kZGRkZGQPZGRLSw8PS0tLS0tLDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPS0tLDw9LS0tLS0tLDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD2QPDw8PD2RkZA9kZGRkZGRkD2RkD2QPS0tLS0tLDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPS0tLDw9LS0tLS0tLDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PD2RkZGQPDw8PD2RkZA8PDw8PDw8PD2RkDw8PS0tLS0tLDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLD0tLS0tLS0tLDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZGQZD2QPGRkZGQ8PDw8PDw8PDw9kZA8PS0tLS0tLDw8PD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLD0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLZA8PDw8PDw8PS0tLS0tLS0tLS0tLS0tLS0sPZA9kZA8PDw8KChkZZGQPDwoKCgoKCg8PDw8PDw8PZA8PS0tLS0sPDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLD0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkS0tLS0tLS0tLSw8PDw8PDw8PDw8PDw9LS0tLS0tLSw9LD2RkDw8PZAoKCgoKGRkZCgoKCgoKCgoPDw9kZA9kZGQPS0tLSw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPD0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD2QPDw8PZA9kGQoKCgoKCgoKCgoKCgoKCgoKDw9kDw9kZGRkZGRkZGRkDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPD0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2QPZA8PZA9kDw8PZAoKCgoKCgoKCgoKCgoKXFxWVlYPXGRkZGQAWgBcXFxcXA9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPD0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0sPS0tLS0sPD0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDwoKCgoKCgoKCgoKCgpcXAAAAABWXFxkZAAAAAAAAAAAD1xcZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPS0tLS0tLS0tLSw9LDw8PZGQPDw8PDw9kZGRkZGRkZGRkZGRkD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkZA8KCgoKCgoKCgoKChlcAAAAAAAAAAAAAAAAAAAAAAAAAFpkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPS0sPDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkD1xcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkZA8PCgoKCgpkZGRkZGQKAAAAAAAAAAAAAAAAAAAAAAAAAFxkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0sPDw8PDw8PD2RkZGRkZA9kDw9WVmRkDw8PZGRkDw8PZGRkZGRkZGRkZFYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PZGRkZA8PDwoKCmRkCgoKGWRkAAAAAAAAAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PS0sPDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPSw8PD2RkZGQPDw8PGRlkDw8ZZGRkAAAAAAAAAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PSw8PD2QPD2RkZGRkZGQPZA8AAAAAAGQAAAAAAAAAAA8PZA8PDw9kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZA8PD2RkZA8PDw8PGWRkDw8PZGRcXFxcAAAAAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PS0sPD2RkZA8PDw9kDw8PAAAAAAAAAAAAAAAAAAAAAABkZA8PD1xkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PD2RkDw8PDw8PDw9kZA8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw9LS0tkZA8PD2RkD2RkDw8AAAAAAAAAAAAAAAAAAAAAAABcZA8PDw9cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGQPD2QPZA8PDw8PDw9kZGRWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLSw8PDw9LS0sPDw8PD2RkZGRkDwAAAAAAAAAAAAAAAAAAAAAAAABkZA8PD2RcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw9kZA8PDw8PDw8PVmRkAAAAAAAAAAAAAAAAAABWVlZkZGRcDw9kD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9LS0tLS0tLS0tLS0tLS0tLSw8PDw9LZA8PD2RkD2RkZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRkXGRWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD1xcAAAAAGQAAAAAAAAAAAAAAAAAAAAAVlZWZGQPDw9kZEtLS0tLS0tLS0tLS0tLS0tLSw8PD0tLDw8PD0tkDw8PD2RkD2RkZA9LSw8PDw9LS2QPD2QPDw9kXGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRcXFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA9kDw8PZGRkZFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXFxcZGQPD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZA8PZGRkZGRkZGRkZGQPDw9kDw8PZGRkZGRkD2RkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PZGRkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXFxcZGQPD2RkD2RkZGRkZGRkZGRkZGRcZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRcXGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw8PWgAAAAAAAAAAAAAAAAAAAAAAAAAAAABkXA8PD2QPD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw8PWgAAAAAAAAAAAAAAAAAAAAAAAAAAAFxcDw8PZGRkD2RkZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw9WXAAAAAAAAAAAAAAAAAAAAAAAAAAAAFwPDw8PZGRkZA8PD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw9kXAAAAAAAAAAAAAAAAAAAAAAAAAAAXFwPDw8PZGRkZGRkDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PXAAAAAAAAAAAAAAAAAAAAAAAAGRkZGRkZGRkZGRkXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZA8PDw8PDw8PXGQAAAAAAAAAAAAAAAAAAAAAAGRkZGRkZGRkZGRkXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PXFwAAAAAAAAAAAAAAAAAAAAAAGQPZGQPZGRkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw8PWgAAAAAAAAAAAAAAAAAAAAAAWmQPDw8PD2RkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw8PXAAAAAAAAAAAAAAAAAAAAABaXGRkXA8PDw9kZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PXAAAAAAAAAAAAAAAAAAAAAAAAABkXGRkZA9cZFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw8PDw9WXAAAAAAAAAAAAAAAAAAAAAAAAAAAZFxkZA9cXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZA8PDw8PDw9WXAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PDw8PDw9WXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PDw8PDw9WZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxcZFxcXFxcXGRcXGRkZFxcXFxkZGRcAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PDw8PDw9cZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFYAAABcXFxcXFxcD2QPDw9kDw8PDw9WXAAAAAAAAAAAWWRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PD2RkDw9cZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWgAAAAAAAAAAAAAAAAAAAABcXFxcXFwAAFxcXFxkZGRkZGRkZGQPZGRkZGRkZFxkZFxcXFxcXGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PZGRkDw9WZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tkZGRkZGQPZGQPZGRkZGRkZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PZGRkDw9WZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkZGQAAAAAAAAAAAAAAABcZFxcXFxcAABaWgBcXFpcXGRkZGRkZGRkZGRkDw8PS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLD0tkS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPD2RkDw9WZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXGRkZGQAAAAAAAAAAAAAAABcZGRkZGRkZGRkZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRaWlpaWlpaXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcGWRkZGRkAAAAAAAAAAAAAFpcZGRkZGRkZEtLS0tLS2RLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVlZWAAAAAAAAAABcD2RkZFxkAAAAAAAAAAAAAABcAABkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1pkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZWAAAAAAAAAFZcD2RkZFxcZAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFkAAABWVg8PD2RkZFxcAAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpaDw8PD2RkZFxcAAAAAAAAAAAAAAAAAAAAZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXA8PDw8PZGRkD1xkAAAAAAAAAAAAAAAAAAAAZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXFxcDw8PZGRkD1xkAAAAAAAAAAAAAAAAAAAAZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpWXFxcVg8PZGRkD1xkAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpaAAAAWg8PZGRkD1xkAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxWAAAAAFYPZGRkD2QAAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVlYAAAAAAFZcZGRkD2QAAAAAAAAAAAAAAAAAAAAAZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWAAAAAAAAAABcZGRkD2QAAAAAAAAAAAAAAAAAAAAAZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZAAAAAAAAAAAAAAAAAAAAAABcZGRkD2QAAAAAAAAAAAAAAAAAAAAAZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaXGRkAAAAAAAAAAAAAAAAAAAAAABcZGRkWlwAAAAAAAAAAAAAAAAAAAAAZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkZAAAAAAAAAAAAAAAAAAAAABcZGRkXAAAAAAAAAAAAAAAAAAAAAAAZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaZGRkZAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkAFYAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAWmQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAXGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAXGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAABZZGRcS0tLSw8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAZGRkZGRkZGRkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaZGRkAAAAAAAAAAAAAAAAAAAAAAAAZAAAZGRkZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGQPDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFwPZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1xkAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaZGRkAAAAAAAAAAAAAAAAAAAAAABaXFxcAAAAZA8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZFxcXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaZGRkAAAAAAAAAAAAAAAAAAAAAABkZGRkZA9cXA8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PXFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaXGRkAAAAAAAAAAAAAAAAAAAAAFxkZGRkZGRkZGQPZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PD1xcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaXGRkAAAAAAAAAAAAAAAAAAAAAGRkZA8PZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA8PDw9cWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaXGRkAAAAAAAAAAAAAAAAAAAAAABkZFwPDw8PD2RkDw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPDw8PVlpaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaXGRkAAAAAAAAAAAAAAAAAAAAAAAAAGRkDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRkDw8PDw9aWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXGRkAAAAAAAAAAAAAAAAAAAAAAAAAFYPDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZA8PDw8PD1paAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcXGRkAAAAAAAAAAAAAAAAAAAAAAAAAFYPDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw9aWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PWlpaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkZAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9kZGRkZGRkDw9aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcD2RkZGRkZGRkZGRkZFpaXFpaWloPDw8PDw8PZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkS2RkZA8PWloAAAAAAAAAAAAAAAAAAAAAAAAAAABWVlYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXFwAAFlcD2RkZA9WD1YPDw8PD2RkZGRkZGRkZGRkZGRkZA9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tLS2RkZGQPD1paAAAAAAAAAAAAAAAAAAAAAAAAAABcVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxWAA9cD2RkZA8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9LS0tLS0sPZGRkDw9aWgAAAAAAAAAAAAAAAAAAAAAAAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcD2RkDw8PDw8PDw8PDw8PDw8PZA8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD0tLS0tLSw8PZGRkZGQPWloAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcD2RkDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZA9kZA8PD1paAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcD2RkDw8PDw8PDw8PDw8PDw9kDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PD0tkZGQPDw8PXFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZXGRkD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLS0sPZGQPDw8PD1xcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw9cXFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw9cXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkDw8PDw8PDw8PDw8PDw8PZA8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkD1xcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZFwPAAAAAAAAAAAAAAAAAFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFwAAABcXGRkD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPAAAAAAAAAAAAAAAAAFxcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXFxcDw8PXGRkDw8PZA8PDw8PDw8PDw8PDw8PDw8PDw8PZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGQPAAAAAAAAAAAAAAAAAFYPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PD2RkD2RkZGRkZGRkZA8PZA8PZA8PZA8PDw8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGRkZABcXFwAAAAAAAAAVg9cXFwAAGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS2RkS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tkZGQPD2RkZGRkZGRkZGRkZGRkZA8PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZA9kZGRkD0tLS0tLS2RkZGRkZEtLZEtkZA9kS2RkZEtkZEtLS0tLS0tLS0tLS2RkZEtLS0tLDw9LS0tLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t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LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRLZEtLSw9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS0tkZGRkZGRkZGRkZGRkZEtLS0tLZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPZGRkZGRkZGRkZGRkZEtkZGRkS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA9LS0tLZGRkZGQPZA8PDw8PD2RkS0tLS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZA9LS0tLDw8PDw8PZGQPZGQPD2RLS0tLSw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA9LS0tLS2RkDw8PD2RkZA8PZEtLS0tLDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw9LS0tLZA8PDw8PDw8PDw9kZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw9LS0sPZA8PDw8PZGRkD2RkZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw9kZGRkDw8PDw9kZGQPDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZGRcD2QPVlZaWg8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tkDw8PDw8PDw9LS0tLS0tLS0tLS0tLS0tLS0tkD2RkDw8PDwAAWlxkZA8PAAAAAAAADw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0sPDw8PDw8PDw8PDw8PS0tLS0tLS0tLS0tkZA8PD1wAAAAAAFpaWgAAAAAAAAAADw8PZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD2QPS0tLZA9kWgAAAAAAAAAAAAAAAAAAAAAADw9kDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PZA9kDw9kD2QPDw9kAAAAAAAAAAAAAAAAAAAAAAAAVg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8AAAAAAAAAAAAAAAAAAAAAAABWVg8PZEtLS0tLS0tLS0tLD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkZA8AAAAAAAAAAAAAAFYAAAAAAAAAVg9kZGRkZGRkZGQPDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZA8AAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLZGRkDw8AAAAAAAAAAAAAXAAAAAAAAAAAD2RkDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS2RLS0tkZGRLS0tkZGRkZGRkS2RkAAAAAAAAAAAAAFxcDw8PDw8PDw8PDw8PDw8PZGQPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8AAAAAAAAAAFxkAAAAAAAAAAAADw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQAAAAAAAAAAAAAAFwPDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PXFxkDw9cZGRkAAAAAAAAAAAADw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS2RkZGRkZGQPZA9kZA8PD2RkZA8PDw8PDw8PZA8PDw9kZAAAAAAAAAAAAAAAXA8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLZGRkDw8PDw9cZGQPDw9kZFYPAAAAAAAAAAAAAAAADw8PZGQPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PD2QPDw8PDw8PAAAAAAAAAA8PDw8PD2RkDw8PD1xkAAAAAAAAAAAAAABcDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD0tkZA8PDw8PDw8PZGQPDw9kDw8AAAAAAAAAAAAAAAAAZGRkZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZA9kZA8PDw8PDwAAAAAAAAAAAA8PDw8PD2QPDw8PD2QPAAAAAAAAAA9cXA8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPD2QPZA8PDw8PDw9kZGQPZGQPDw8AAAAAAAAAAAAAAABkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkDw8PAAAAAAAAAAAAAAAAAA8PDw9kZA8PD2QPZA8AAAAAAAAAXFxcDw8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PD2RkDw8PDw8PDw8PZGRkZGQPXA8AAAAAAAAAAAAAAGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PZGQPZGRkZGQPDwAAAAAAAAAAAAAAAAAAAA8PDw9kZGQPZA8PDw8AAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw9kZGRkZGRkZA8AAAAAAAAAAAAPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tkDw9kDw8PZA9kZA8PAAAAAAAAAAAAAAAAAAAAAA8PD2RkD1xcDw8PDwAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9kS0sPZGRkZA8PDw8PZGRkZGQPDw8PAAAAAAAAAAAADw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLD2RkZGRkDwAAAAAAAAAPDw8AAAAAAAAAAA8PDw8PDwAAAAAAAAAAAAAAAAAPDwAAAAAAAAAPDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkSw8PD0tkZGRkZGQPD2RkDw9kZA8PDwAAAAAAAAAAAAAPDw9kZEtLZGQPS0tLS2RLZGRkZGRkZA9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tkS0tLS0tLS1xcZGRkZA8AAAAAAAAADw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPS0sPD0tLDw9kDw8PDw8PD2RkDw8AAAAAAAAAAAAAAA8PDw9kS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZA8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD0sPDw9LD2QPDw8PDw8PD2QPAAAAAAAAAAAAAAAPDw8PZGRLS2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PZGQPDw8PDw8PDwAAAAAAAAAAAAAADw8PDw9kZGRLS0sPZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PZA9kZA8PDw8PDw8PAAAAAAAAAFxcXFwPDw8PD2RkZGRkZA9kZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw9kDw8PDw8PDwAAAAAAAABcXGRkZGRkZGRkZGRkD2RkDw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PDw8PZGQPDw8PDw8PAAAAAAAAAFxkZGRkZGRkZGRkZGQPD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8AAAAAAAAAAFYPDwAAAAAAAA8PDwAAAAAAAAAAAAAAAAAAAAAPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PZGQPDw8PDw8AAAAAAAAAXGRkD2RkD2RkZGRkDw8PD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAWVZWWgAAAAAPDw8PDw8PDw8PDw8AAAAAAAAAAA9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw9kZA8PDw8PAAAAAAAAAA8PD2QPDw8PD2RkZGRkDw8PD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAABWDw8PWg8PD2QPDw8PDw8PDw8PDw8PAAAAAAAAD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PD2QAAAAPDwAAAAAAAAAADw8PZGQPDw8PD2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAFoPDw8PDw9cZGRkZA8PDw8PDw8PD1xcAAAAAAAPZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw9cAAAAAAAAAAAAAAAAAAAPDw9kZA9kZGQPD2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAWg8PDw8PDw9kDw8PZGRkZGRkZGRkZGQAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD1wAAAAAAAAAAAAAAAAAAA8PD2RkZA9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAA8PDw8PDw8PDw8PDw9kZA8PDw9kZGRkZA8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PZAAAAAAAAAAAAAAAAAAADw8PD2RkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kDw8PD2RkS0tLDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw8PDw9kAAAAAAAAAAAAAAAAAAAADw8PZGRkZGRkZGQPDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkDw9kDw8PZA8PDw8PZGRLSw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLS2RkAAAAAAAAAA8AAAAAAAAAAA8PZGRkZGRkZA8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PDw8PD2QPD2RkZA8PDw9kZEsPDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PS0tkZGQAAAAAAA8PDwAAAAAAAAAAAA9kZGQPD2QPDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PD2QPDw8PDw8PSw9kDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PS2RkZAAAAAAADw8PDwAAAAAAAAAAAA8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkD2RkZGRkZGQPZGQPDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9LZGRkAAAAAAAPDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXA8PD1xcAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tkZGRkZGQPZGQPS2RkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZGQAAAAAAA8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PAAAAAAAAAAAAAABcZGRkZGQPAAAAAAAAAAAAAABcDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRLS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9kZA8PD2RkZAAAAAAADw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDwAAAAAAAAAAAAAAAFxkZGRkZGQPAAAAAAAAAAAAAGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAPXGRkZGRkZA8PAAAAAAAAAABcZGRkZGRkZEtLS0tLS2RLS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PDw8PDwAAAAAAAAAPDw8PDw8PZGRkD2RkZA8PAAAAAAAAD1xkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAADw8PDw8PDw9kZGQPD2RkDw8PAAAAAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAA8PDw8PDw8PD2RkZA8PZGQPDw8AAAAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAPDw8PDw8PDw8PZGRkDw9kDw8PDwAADwAAAAAAAABcZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw9kZA8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAADw8PDw8PDw8PD2RkZA8PZA8PDw8PDwAAAAAAAAAAXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAA8PDw8PDw8PDw8PZGRkDw9kDw8PDw8PAAAAAAAAAABcZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAPDw8PDw8PDw8PDw9kZGQPD2QPDw9kZA8PAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAADw8PDw8PDw8PDw8PD2RkZA8PZA8PDw9kZA8AAAAAAAAPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAADw8PDw8PDw8PDw8PZGRkD2RkDw8PDw9kDwAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAADw8PDw8PDw8PDw9kZGQPZGQPDw8PD2RkAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAPDw8PDw8PDw8PD2RkZA9kZA8PDw8PXAAAAAAAAAAPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAA8PDw8PDw8PDw8PZGRkD2RkDw8PAAAAAAAAAAAAAA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8AAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkAAAAAAAADw8PDw8PDw8PDw9kZGQPD2QPDwAAAAAAAAAAAAAADw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPAAAAAAAPDw8PDw8PDw8PD2RkZA8PDw8PAAAAAAAAAAAAAAAPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZA8AAAAAAA8PDw8PDw8PDw8PZGRkDw8PDw8AAAAAAAAAAAAADw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8AAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9cZGQPAAAAAAAADw8PDw8PDw8PDw9kZGQPDw8PDwAAAAAAAAAAAA8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAPDw8PDw8PDw8PD2RkZGQPDw8PAAAAAAAAAAAADw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PZGRkDw8PDw8PAAAAAAAAAAAPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw9kZGQPDw8PDw8AAAAAAAAAAA8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8AAAAAAA8PAAAADw8PDw8PDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAA8PDw8PDw8PDw8PD2RkZA8PDw8PDwAAAAAAAAAPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwAAAAAADwAAAAAADw8PDw8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PZGRkDw8PDw8PAAAAAAAAAA8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8AAAAAAAAADw8PDw9kZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PAAAAAAAAAAAPDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDwAAAAAAAAAAAA8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PAAAAAAAAAAAADw8PDw8PDw8PDw9kZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8AAAAAAAAAAAAPDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwAAAAAAAAAADw8PAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8AAAAAAAAAAA8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PAAAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8AAAAAAAAADw8PDw8PDw8PDw9kDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwAAAAAAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPDw8PDw8AAAAAAAAPDw8PZGRkZGQPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkDw8PDw8PDw8AAAAAAAAPDw9kZGRkZGRkZGQPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PVgAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPDw8PDw8PDwAAAAAAAAAPZGRkS0tkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw9WAAAAAAAAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PAAAAAAAAAABcZGRLDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PD1kAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8AAAAAAAAAAABWZGRkDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PD1oAAAAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8AAAAAAAAAAA8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGQPDw8PDw8PWVoAAA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw8AAAAAAAAADw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PDwAAAAAAAA8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGQPDw8PDw8PDw8PDw8PD2RkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZEtkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkSw8PDw8PDw8PDw9kZGQPDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLDw8PDw8PDw8PDw8PD2QPDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0sPDw8PDw8PDw8PZGRkDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLDw8PDw8PDw8PDw8PD2QPDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtkDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLDw8PDw8PDw8PDw8PD2QPDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkSw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEsPD2QPDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2RkZGRkZGRkZA8PZA8PZA8PZA8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLZGRLS2RkZGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tLZGRkS0tkZGRkZGRkZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZEtkZGRkS0tLS0tLS2RkZGRkZEtLZEtkZA9kS2RkZEtkZEtLS0tLS0tLS0tLS2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQAFKDw18dOy+FfXTwbwdhp0ZPVUAAIA/WOMSqgHtuQINj8J1PRIKDUfhBsEV4Xq0vxi/ASBpMtecAUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkS2RLS0sPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGRkZGRkS2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tLZGRkZGRkZGRkZGRkZGRLS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkD2RkZGRkZGRkZGRkZGRLZGRkZEtLZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPS0tLS2RkZGRkD2QPDw8PDw9kZEtLS0tLZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPZGQPS0tLSw8PDw8PD2RkD2RkDw9kS0tLS0sPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPS0tLS0tkZA8PDw9kZGQPD2RLS0tLSw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PS0tLS2QPDw8PDw8PDw8PZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PS0tLD2QPDw8PD2RkZA9kZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PZGRkZA8PDw8PZGRkDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PD2RkXA9kD1ZWWloPDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLZA8PDw8PDw8PS0tLS0tLS0tLS0tLS0tLS0tLZA9kZA8PDw8KClpcZGQPDwoKCgoKCg8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLDw8PDw8PDw8PDw8PD0tLS0tLS0tLS0tLZGQPDw9cCgoKCgpaWloKCgoKCgoKCg8PD2RkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLSw8PDw8PDw8PDw8PDw9kD0tLS2QPZFoKCgoKCgoKCgoKCgoKCgoKCg8PZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD2QPZA8PZA9kDw8PZAoKCgoKCgoKCgoKCgoKCgoKClYPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKVlYPD2RLS0tLS0tLS0tLSw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw9kZGQPCgoKCgoKCgoKCgpWCgoKCgoKClYPZGRkZGRkZGRkDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLD2QPCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9LS2RkZA8PCgoKCgoKCgoKClwKCgoKCgoKCg9kZA8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS0tkS0tLZGRkS0tLZGRkZGRkZEtkZAoKCgoKCgoKCgpcXA8PDw8PDw8PDw8PDw8PD2RkD0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PCgoKCgoKCgpcZAoKCgoKCgoKCg8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkCgoKCgoKCgoKCgpcDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PD1xcZA8PXGRkZAoKCgoKCgoKCg8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tkZGRkZGRkD2QPZGQPDw9kZGQPDw8PDw8PD2QPDw8PZGQKCgoKCgoKCgoKClwPDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS2RkZA8PDw8PXGRkDw8PZGRWDwoKCgoKCgoKCgoKCg8PD2RkDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw9kDw8PDw8PDwoKCgoKCgoPDw8PDw9kZA8PDw9cZAoKCgoKCgoKCgoKXA8PDw8PDw8PDw8PDw8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9LZGQPDw8PDw8PD2RkDw8PZA8PCgoKCgoKCgoKCgoKCmRkZGQPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PZGQPZGQPDw8PDw8KCgoKCgoKCgoPDw8PDw9kDw8PDw9kDwoKCgoKCgoPXFwPDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw9kD2QPDw8PDw8PZGRkD2RkDw8PCgoKCgoKCgoKCgoKZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRkZA8PDwoKCgoKCgoKCgoKCgoPDw8PZGQPDw9kD2QPCgoKCgoKClxcXA8PDw8PDw8PDw8PDw8PDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw9kZA8PDw8PDw8PD2RkZGRkD1wPCgoKCgoKCgoKCgpkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PD2RkD2RkZGRkDw8KCgoKCgoKCgoKCgoKCgoPDw8PZGRkD2QPDw8PCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGQPCgoKCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RLS0tLS0tLS0tLS0tLS0tLS0tLZA8PZA8PD2QPZGQPDwoKCgoKCgoKCgoKCgoKCgoPDw9kZA9cXA8PDw8KCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPZEtLD2RkZGQPDw8PD2RkZGRkDw8PDwoKCgoKCgoKCg8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLSw9kZGRkZA8KCgoKCgoKDw8PCgoKCgoKCgoPDw8PDw8KCgoKCgoKCgoKCgoKDw8KCgoKCgoKDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEsPDw9LZGRkZGRkDw9kZA8PZGQPDw8KCgoKCgoKCgoKDw8PZGRLS2RkD0tLS0tkS2RkZGRkZGQPZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tLZEtLS0tLS0tcXGRkZGQPCgoKCgoKCg8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkD0tLDw9LSw8PZA8PDw8PDw9kZA8PCgoKCgoKCgoKCgoPDw8PZEtLZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQPDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw9LDw8PSw9kDw8PDw8PDw9kDwoKCgoKCgoKCgoKDw8PD2RkS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD2RkDw8PDw8PDw8KCgoKCgoKCgoKCg8PDw8PZGRkS0tLD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PD2QPZGQPDw8PDw8PDwoKCgoKCgpcXFxcDw8PDw9kZGRkZGQPZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PZA8PDw8PDw8KCgoKCgoKXFxkZGRkZGRkZGRkZA9kZA8PZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw9kZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPDw8PDw8PD2RkDw8PDw8PDwoKCgoKCgpcZGRkZGRkZGRkZGRkDw9kZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PCgoKCgoKCgpWDw8KCgoKCgoPDw8KCgoKCgoKCgoKCgoKCgoKD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkDw8PDw8PDw8PD2RkDw8PDw8PCgoKCgoKClxkZA9kZA9kZGRkZA8PDw9kZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCllWVloKCgoKDw8PDw8PDw8PDw8PCgoKCgoKCgoPZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPDw8PDw8PDw8PZGQPDw8PDwoKCgoKCgoPDw9kDw8PDw9kZGRkZA8PDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKVg8PD1oPDw9kDw8PDw8PDw8PDw8PDwoKCgoKCg9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw9kCgoKDw8KCgoKCgoKCg8PD2RkDw8PDw9kZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgpaDw8PDw8PXGRkZGQPDw8PDw8PDw9cXAoKCgoKD2RkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PXAoKCgoKCgoKCgoKCgoKDw8PZGQPZGRkDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCloPDw8PDw8PZA8PD2RkZGRkZGRkZGRkCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw9cCgoKCgoKCgoKCgoKCgoPDw9kZGQPZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoPDw8PDw8PDw8PDw8PZGQPDw8PZGRkZGQPDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA8PDw8PDw8PD2QKCgoKCgoKCgoKCgoKCg8PDw9kZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZA8PDw9kZEtLSw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSw8PDw8PZAoKCgoKCgoKCgoKCgoKCg8PD2RkZGRkZGRkDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkZA8PZA8PD2QPDw8PD2RkS0sPDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLDw9LS0tkZAoKCgoKCgoPCgoKCgoKCgoPD2RkZGRkZGQPDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QPDw8PDw9kDw9kZGQPDw8PZGRLDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0sPD0tLZGRkCgoKCgoPDw8KCgoKCgoKCgoPZGRkDw9kDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2QPDw9kDw8PDw8PD0sPZA8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2QPD0tkZGQKCgoKCg8PDw8KCgoKCgoKCgoPDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZA9kZGRkZGRkD2RkDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PS2RkZAoKCgoKDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKClwPDw9cXAoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS0tLZGRkZGRkD2RkD0tkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PZGRkCgoKCgoPDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDwoKCgoKCgoKCgoKXGRkZGRkDwoKCgoKCgoKCgoKXA8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkS0tLS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkS0tLS2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PZGQPDw9kZGQKCgoKCg8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8KCgoKCgoKCgoKCgpcZGRkZGRkDwoKCgoKCgoKCgpkZGRkZGRkZGRkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKD1xkZGRkZGQPDwoKCgoKCgoKXGRkZGRkZGRLS0tLS0tkS0tkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PD2RkZA9kZGQPDwoKCgoKCg9cZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PZGRkDw9kZA8PDwoKCgoKCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw9kZGQPD2RkDw8PCgoKCgoKCgoKClxkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw8PD2RkZA8PZA8PDw8KCg8KCgoKCgoKXGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PZGQPDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw9kZGQPD2QPDw8PDw8KCgoKCgoKClxkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PD2RkZA8PZA8PDw8PDwoKCgoKCgoKXGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKDw8PDw8PDw8PDw8PZGRkDw9kDw8PZGQPDwoKCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw8PDw9kZGQPD2QPDw8PZGQPCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw8PD2RkZA9kZA8PDw8PZA8KCgoKCgoPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCg8PDw8PDw8PDw8PZGRkD2RkDw8PDw9kZAoKCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw9kZGQPZGQPDw8PD1wKCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw8PD2RkZA9kZA8PDwoKCgoKCgoKCgoPD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZAoKCgoKCg8PDw8PDw8PDw8PZGRkDw9kDw8KCgoKCgoKCgoKCg8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8KCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkDwoKCgoKDw8PDw8PDw8PDw9kZGQPDw8PDwoKCgoKCgoKCgoKDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZGQPCgoKCgoPDw8PDw8PDw8PD2RkZA8PDw8PCgoKCgoKCgoKCg8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PXGRkDwoKCgoKCg8PDw8PDw8PDw8PZGRkDw8PDw8KCgoKCgoKCgoPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8KCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKDw8PDw8PDw8PDw9kZGRkDw8PDwoKCgoKCgoKCg8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDwoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PD2RkZA8PDw8PDwoKCgoKCgoKDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDwoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PZGRkDw8PDw8PCgoKCgoKCgoPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PCgoKCgoPDwoKCg8PDw8PDw8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoPDw8PDw8PDw8PDw9kZGQPDw8PDw8KCgoKCgoKDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCg8KCgoKCg8PDw8PDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PD2RkZA8PDw8PDwoKCgoKCgoPDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PCgoKCgoKCg8PDw8PZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8KCgoKCgoKCgoPDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDwoKCgoKCgoKCg8PDw8PDw8PDw8PZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PCgoKCgoKCgoKDw8PDw8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDw8KCgoKCgoKCg8PDwoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDwoKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw8PZA8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8KCgoKCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGRkDw8PDw8PCgoKCgoKDw8PD2RkZGRkDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGQPDw8PDw8PDw8PDwoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZA8PDw8PDw8PCgoKCgoKDw8PZGRkZGRkZGRkD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PD1YKCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkDw8PDw8PDw8KCgoKCgoKD2RkZEtLZGRkZGRkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PVgoKCgoKCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGQPDw8PDw8PDwoKCgoKCgoKXGRkSw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw9ZCgoKCgoKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PCgoKCgoKCgoKVmRkZA8PDw8PZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw9aCgoKCg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PCgoKCgoKCgoPDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkDw8PDw8PD1laCgoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkDw8PDw8PDw8PCgoKCgoKCg8PDw8PDw8PDw9kZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw8KCgoKCgoPDw8PDw8PDw8PD2RkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRkZGRkZGRkZGRkDw8PDw8PDw8PDw8PDw9kZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZEtkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZGQPDw8PDw8PDw9kZGRkZGRkZGRkZGRkZGRLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkZEsPDw8PDw8PDw8PZGRkDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGQPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLSw8PDw8PDw8PDw8PDw9kDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtLDw8PDw8PDw8PD2RkZA8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZA9kZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkSw8PDw8PDw8PDw8PDw9kDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtkDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2QPDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLSw8PDw8PDw8PDw8PDw9kDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEsPDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD2RkS2RkDw8PDw8PDw8PDw8PDw8PDw8PDw8PZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PZGRLDw9kDw8PDw8PDw8PDw8PDw8PDw8PDw9kS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw9kZEtkZGRkZGRkZGQPD2QPD2QPD2QPDw8PD2RLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZA8PDw8PDw8PDw8PDw8PDw8PD2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkS2RkS0tkZGRkZGRkZGRkZGRkZGRkZGRkZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRLS0tLS2RkZEtLZGRkZGRkZGRkZGRkZGRkS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS2RkZGRkZGRkZGRkZGRLZGRkZEtLS0tLS0tkZGRkZGRLS2RLZGQPZEtkZGRLZGRLS0tLS0tLS0tLS0tkZGRLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLZEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSz0AAMhCQAFKDw18dOy+FfXTwbwdhp0ZPVUAAIA/WOMSmgHXnAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAQEBAQEBAQEBAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAAABAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAAAAAwMDAwMDAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAADAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAAABAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAgICAAICAgICAgICAgICAgICAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAgICAgICAgICAAACAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAwMDAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAMDAwMDAwMDAwMDAwADAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAADAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAADAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAADAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAMDAwAAAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAADAwMDAwADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAMDAwMDAAADAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAwMDAwMAAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAADAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAADAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAADAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAADAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwAAAAADAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAQG4AQHIAQTQAQHYAQHiAYsNEgRlZGdlIoINCgwNFK6vwBUpXE+/GAAKDA0ehbPAFdejML8YAQoMDShct8AV16MwvxgCCgwNMjO7wBWF6xG/GAMKDA08Cr/AFYXrEb8YBAoMDcL1wMAVrkchvxgFCgwNULjGwBWuRyG/GAYKDA3Wo8jAFYXrEb8YBwoMDdajyMAVcD2KvhgICgwNULjGwBVACle+GAkKDA3C9cDAFUAKV74YCgoMDTwKv8AVcD2KvhgLCgwNonC1wBVwPYq+GAwKDA0ehbPAFcT1qL4YDQoMDR6Fs8AVFK7HvhgOCgwNmJmxwBVmZua+GA8KDA0Urq/AFRSux74YEAoMDRSur8AVcD2KvhgRCgwNjsKtwBVACle+GBIKDA2Owq3AFfBRuL0YEwoMDf//p8AV8FG4PRgUCgwNhOupwBWYmRk+GBUKDA2Owq3AFZiZGT4YFgoMDRSur8AVQApXPhgXCgwNFK6vwBXE9ag+GBgKDA2YmbHAFRSuxz4YGQoMDaJwtcAVcD2KPhgaCgwNtx69wBVwPYo+GBsKDA08Cr/AFcT1qD4YHAoMDTwKv8AVhOsRPxgdCgwNtx69wBWuRyE/GB4KDA23Hr3AFdajMD8YHwoMDcL1wMAVKlxPPxggCgwNwvXAwBWicH0/GCEKDA08Cr/AFWdmhj8YIgoMDTwKv8AVzcysPxgjCgwNwvXAwBXherQ/GCQKDA3MzMTAFeF6tD8YJQoMDVC4xsAVzcysPxgmCgwNW4/KwBXNzKw/GCcKDA3geszAFeF6tD8YKAoMDepR0MAV4Xq0PxgpCgwNbz3SwBX1KLw/GCoKDA1vPdLAFR+Fyz8YKwoMDfQo1MAVMzPTPxgsCgwN9CjUwBW4HlVAGC0KDA1lZs7AFdijYEAYLgoMDeB6zMAV2KNgQBgvCgwN1qPIwBXsUWhAGDAKDA3MzMTAFexRaEAYMQoMDUbhwsAV4npkQBgyCgwNRuHCwBXMzFxAGDMKDA3C9cDAFcL1WEAYNAoMDbcevcAV2KNgQBg1CgwNPAq/wBXiemRAGDYKDA08Cr/AFfYobEAYNwoMDa1HucAVFK53QBg4CgwNKFy3wBUUrndAGDkKDA2icLXAFR6Fe0AYOgoMDaJwtcAVH4WDQBg7CgwNmJmxwBUpXIdAGDwKDA0Urq/AFSlch0AYPQoMDXoUpsAVw/WQQBg+CgwNo3CFwBXD9ZBAGD8KDA0ehYPAFT0Kj0AYQAoMDTwKJ8AVPQqPQBhBCgwNMjMjwBW4Ho1AGEIKDA0yMyPAFaRwTUAYQwoMDTwKJ8AVmplJQBhECgwNPAonwBVH4do/GEUKDA0yMyPAFTMz0z8YRgoMDTIzI8AV9Si8PxhHCgwNPAonwBXherQ/GEgKDA08CifAFSpcTz8YSQoMDY7CRcAVxPWoPhhKCgwNCNdzwBXE9ag+GEsKDA0SrnfAFRSuxz4YTAoMDRKud8AVhOsRPxhNCgwNHIV7wBWuRyE/GE4KDA0mXH/AFa5HIT8YTwoMDR6Fg8AV/v8/PxhQCgwNo3CFwBXWozA/GFEKDA2tR4nAFdajMD8YUgoMDTwKj8AVUrhePxhTCgwNPAqPwBVnZoY/GFQKDA1G4ZLAFY/ClT8YVQoMDeB6nMAVj8KVPxhWCgwNZWaewBV7FI4/GFcKDA1lZp7AFWdmhj8YWAoMDepRoMAVonB9PxhZCgwN6lGgwBV6FG4/GFoKDA1wPaLAFVK4Xj8YWwoMDXA9osAV/v8/PxhcCgwNehSmwBWuRyE/GF0KDA16FKbAFVyPAj8YXgoMDXA9osAVFK7HPhhfCgwN4HqcwBUUrsc+GGAKDA1bj5rAFWhm5j4YYQoMDczMlMAVaGbmPhhiCgwNRuGSwBUUrsc+GGMKDA1G4ZLAFfBRuD0YZAoMDczMlMAVgML1PBhlCgwNzMyUwBXwUbi9GGYKDA1G4ZLAFZiZGb4YZwoMDUbhksAVcD2KvhhoCgwNzMyUwBXE9ai+GGkKDA1bj5rAFcT1qL4YagoMDeB6nMAVcD2KvhhrCgwNZWaewBVwPYq+GGwKDA3qUaDAFcT1qL4YbQoMDXA9osAVxPWovhhuCgwN9CikwBUUrse+GG8KDA16FKbAFRSux74YcAoMDf//p8AVZmbmvhhxCgwN//+nwBVcjwK/GHIKDA16FKbAFYXrEb8YcwoMDXoUpsAVAABAvxh0CgwN//+nwBUpXE+/GHUKDA0Urq/AFSlcT78YduIBuwMSBGVkZ2UisgMKDA2AFI4/FXsUjr8YAAoMDWhmhj8VZmaGvxgBCgwNaGaGPxUpXE+/GAIKDA2wcH0/FQAAQL8YAwoMDbBwfT8VXI8CvxgECgwNgBSOPxUUrse+GAUKDA2AFI4/FYDC9bwYBgoMDWhmhj8VgML1PBgHCgwNaGaGPxWE6xE/GAgKDA2QwpU/FYTrET8YCQoMDbgepT8V1qMwPxgKCgwN6Hq0PxXWozA/GAsKDA34KLw/Fa5HIT8YDAoMDRDXwz8V1qMwPxgNCgwNODPTPxXWozA/GA4KDA1I4do/Ff7/Pz8YDwoMDfgoDEAV/v8/PxgQCgwNAAAQQBXWozA/GBEKDA0M1xNAFdajMD8YEgoMDRiuF0AV/v8/PxgTCgwNGK4XQBVSuF4/GBQKDA0M1xNAFXoUbj8YFQoMDQzXE0AVZ2aGPxgWCgwNIIUbQBWPwpU/GBcKDA1ACidAFY/ClT8YGAoMDUjhKkAVexSOPxgZCgwNSOEqQBWkcH2/GBoKDA1ACidAFWZmhr8YGwoMDUjh2j8VZmaGvxgcCgwNODPTPxV7FI6/GB0KDA2AFI4/FXsUjr8YHuIBxwsSBGVkZ2UivgsKDA2AmRm+FUAKV74YAAoMDQAKV74VmJkZvhgBCgwNWI8CvxWYmRm+GAIKDA2A6xG/FfBRuL0YAwoMDYDrEb8VmJkZPhgECgwN0KMwvxVwPYo+GAUKDA34/z+/FXA9ij4YBgoMDSBcT78VxPWoPhgHCgwNeBSOvxXE9ag+GAgKDA2MwpW/FRSuxz4YCQoMDUTh2r8VFK7HPhgKCgwNWI/ivxXE9ag+GAsKDA2C60HAFcT1qD4YDAoMDTIzI8AVKlxPPxgNCgwNMjMjwBWPwpU/GA4KDA0mXB/AFaNwnT8YDwoMDRKuF8AVo3CdPxgQCgwNCNcTwBWPwpU/GBEKDA3+/w/AFY/ClT8YEgoMDfQoDMAVo3CdPxgTCgwN9CgMwBW5HqU/GBQKDA3qUQjAFc3MrD8YFQoMDepRCMAV4Xq0PxgWCgwN4HoEwBX1KLw/GBcKDA3gegTAFUfh2j8YGAoMDdSjAMAVW4/iPxgZCgwNlJn5vxVbj+I/GBoKDA1sPeq/FYXr8T8YGwoMDWw96r8VmZn5PxgcCgwNWI/ivxXWowBAGB0KDA2A6/G/FexRCEAYHgoMDZSZ+b8V4noEQBgfCgwNlJn5vxWZmfk/GCAKDA3UowDAFYXr8T8YIQoMDepRCMAVhevxPxgiCgwN9CgMwBWZmfk/GCMKDA30KAzAFfYoDEAYJAoMDQjXE8AVCtcTQBglCgwNCNcTwBUehRtAGCYKDA0SrhfAFShcH0AYJwoMDRKuF8AVkMJFQBgoCgwNCNcTwBWamUlAGCkKDA0SrhfAFaRwTUAYKgoMDRKuF8AVuB5VQBgrCgwNCNcTwBXC9VhAGCwKDA0I1xPAFeJ6ZEAYLQoMDf7/D8AV7FFoQBguCgwNbD3qvxXsUWhAGC8KDA1Yj+K/FfYobEAYMAoMDZhwfb8V9ihsQBgxCgwNcBRuvxXsUWhAGDIKDA1IuF6/FexRaEAYMwoMDSBcT78V4npkQBg0CgwNIFxPvxXMzFxAGDUKDA1wFG6/FbgeVUAYNgoMDWRmhr8VuB5VQBg3CgwNjMKVvxXMzFxAGDgKDA3IzKy/FczMXEAYOQoMDfAovL8VuB5VQBg6CgwN8Ci8vxWuR1FAGDsKDA3cerS/FaRwTUAYPAoMDdx6tL8VmplJQBg9CgwNyMysvxWQwkVAGD4KDA1kZoa/FZDCRUAYPwoMDZhwfb8VhutBQBhACgwNmHB9vxVmZjZAGEEKDA1kZoa/FVyPMkAYQgoMDbQepb8VXI8yQBhDCgwNyMysvxVSuC5AGEQKDA3IzKy/FT4KJ0AYRQoMDbQepb8VMjMjQBhGCgwNtB6lvxUUrhdAGEcKDA3IzKy/FQrXE0AYSAoMDcjMrL8VcT3qPxhJCgwN3Hq0vxVbj+I/GEoKDA3cerS/FR+Fyz8YSwoMDfAovL8VCdfDPxhMCgwNCNfDvxUJ18M/GE0KDA0chcu/FfUovD8YTgoMDRyFy78V4Xq0PxhPCgwNCNfDvxXNzKw/GFAKDA0I18O/FbkepT8YUQoMDfAovL8Vo3CdPxhSCgwN3Hq0vxW5HqU/GFMKDA2oRyG/FbkepT8YVAoMDViPAr8Vj8KVPxhVCgwNgBRuPxWPwpU/GFYKDA2wcH0/FXsUjj8YVwoMDbBwfT8VUrhePxhYCgwNgBRuPxUqXE8/GFkKDA2AFG4/FYTrET8YWgoMDbBwfT8VXI8CPxhbCgwNsHB9PxXwUbg9GFwKDA2AFG4/FZiZGT4YXQoMDeCjMD8VmJkZPhheCgwNsEchPxXwUbg9GF8KDA2wRyE/FYDC9TwYYAoMDZDrET8VgML1vBhhCgwNkOsRPxWYmRm+GGIKDA1gjwI/FUAKV74YYwoMDUAKVz4VQApXvhhkCgwNwJkZPhWYmRm+GGUKDA0AxPU8FZiZGb4YZgoMDQDC9bwVQApXvhhnCgwNgJkZvhVACle+GGjiASQSBGRvb3IiHAoMDY7CRcAVxPWoPhgACgwNPAonwBWjcJ0/GAHiASQSBGRvb3IiHAoMDWhmhj8VgML1PBgACgwNaGaGPxWE6xE/GAFKCAgDQGRIAFgUUAGCARcKABgAIAAoADAAWABgAIABAIgBApoBAPgBAZgCAqACAugCAA== \ No newline at end of file diff --git a/tests/fixtures/sharkiq_status_frame.b64 b/tests/fixtures/sharkiq_status_frame.b64 new file mode 100644 index 0000000..46ec5f0 --- /dev/null +++ b/tests/fixtures/sharkiq_status_frame.b64 @@ -0,0 +1 @@ +COimzQEQSiAOSggIA0BkSABYFFABggEXCgAYACAAKAAwAFgAYACAAQCIAQKaAQCYAgKgAgLoAgA= \ No newline at end of file diff --git a/tests/test_client.py b/tests/test_client.py index 9ddee06..ea823ed 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -15,7 +15,18 @@ ConnectError, SharklocalError, ) -from sharklocal.models import DeviceInfo, ProbeResult, VacuumEvent, VacuumMode, VacuumStatus +from sharklocal.models import ( + DeviceInfo, + MapGrid, + MapPoint, + MapRoom, + ProbeResult, + SuctionLevel, + VacuumEvent, + VacuumMap, + VacuumMode, + VacuumStatus, +) # --------------------------------------------------------------------------- @@ -576,3 +587,280 @@ async def test_stop_monitoring_cancels_task(): await client.stop_monitoring() assert client._monitor_task is None assert client._monitor_stop is None + + +# --------------------------------------------------------------------------- +# Settings and locate actions → _execute() call with correct action name +# --------------------------------------------------------------------------- + + +@pytest.mark.parametrize( + "method_name, args, expected_action", + [ + ("find_robot", (), "find_robot"), + ("request_map", (), "request_map"), + ("set_suction", (SuctionLevel.ECO,), "set_suction_eco"), + ("set_suction", ("normal",), "set_suction_normal"), + ("set_suction", (SuctionLevel.MAX,), "set_suction_max"), + ("set_recharge_resume", (True,), "recharge_resume_on"), + ("set_recharge_resume", (False,), "recharge_resume_off"), + ("set_evac_resume", (True,), "evac_resume_on"), + ("set_evac_resume", (False,), "evac_resume_off"), + ("pause", (), "pause"), + ("edge_clean", (), "edge_clean"), + ], +) +async def test_setting_actions_call_execute(method_name, args, expected_action): + client = _make_vacuum_client_with_mocks() + with patch.object(client, "_execute", new_callable=AsyncMock) as mock_exec: + mock_exec.return_value = True + await getattr(client, method_name)(*args) + mock_exec.assert_awaited_once_with(expected_action) + + +@pytest.mark.parametrize( + "name, enabled, captured", + [ + # The app's own Recharge & Resume / Evac & Resume commands. + ("recharge_resume", True, "OgJAAQ=="), + ("recharge_resume", False, "OgJAAg=="), + ("evac_resume", True, "OgI4AQ=="), + ("evac_resume", False, "OgI4Ag=="), + ], +) +async def test_toggle_writer_reproduces_the_app_captures(name, enabled, captured): + import base64 + + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(return_value=True) + assert await client.set_toggle(name, enabled) is True + client._mqtt.send.assert_awaited_once_with(base64.b64decode(captured)) + + +async def test_settings_write_their_config_fields(): + from sharklocal import protobuf + + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(return_value=True) + await client.set_toggle("do_not_disturb", True) + await client.set_carpet_detect(2) + await client.set_volume(7) + sent = [call.args[0] for call in client._mqtt.send.await_args_list] + assert sent == [ + protobuf.encode_bytes_field(7, protobuf.encode_varint_field(18, 1)), + protobuf.encode_bytes_field(7, protobuf.encode_varint_field(15, 2)), + protobuf.encode_bytes_field(7, protobuf.encode_varint_field(2, 7)), + ] + + +async def test_unknown_toggle_is_refused(): + client = _make_vacuum_client_with_mocks() + with pytest.raises(ValueError, match="turbo"): + await client.set_toggle("turbo", True) + + +def test_mapping_carries_the_new_commands(): + import base64 + + from sharklocal.mappings import load_mqtt_mapping + + actions = load_mqtt_mapping("sharkiq_v1").actions + assert base64.b64decode(actions["pause"].payload) == bytes([0x80, 0x01, 8]) # 16 = USR_CTR_PAUSE + assert base64.b64decode(actions["start_cleaning"].payload) == bytes([0x80, 0x01, 9]) # USR_CTR_RESUME + assert base64.b64decode(actions["edge_clean"].payload) == bytes([0x80, 0x01, 16]) # USR_CTR_ALONG_WALL + assert base64.b64decode(actions["explore"].payload) == bytes([0x80, 0x01, 38]) # USR_CTR_AUTO_EXPLORE + + +async def test_set_suction_rejects_unknown_level(): + client = _make_vacuum_client_with_mocks() + with pytest.raises(ValueError): + await client.set_suction("turbo") + + +# --------------------------------------------------------------------------- +# clean_rooms() / clean_spot() — room definition, then start +# --------------------------------------------------------------------------- + + +def _persisted_map(persisted: bool = True) -> VacuumMap: + grid = MapGrid(resolution=0.06, width=1, height=1, origin=MapPoint(0.0, 0.0), cells=b"\x0f") + room = MapRoom(name="Kitchen", polygon=[MapPoint(0, 0), MapPoint(1, 0), MapPoint(1, 1), MapPoint(0, 1)]) + return VacuumMap(grid=grid, persisted=persisted, map_id="ABCD1234", rooms=[room]) + + +async def test_clean_rooms_sends_selection_then_starts(): + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(return_value=True) + with patch.object(client, "_execute", new_callable=AsyncMock) as mock_exec: + mock_exec.return_value = True + result = await client.clean_rooms(["Kitchen"], vacuum_map=_persisted_map()) + assert result is True + client._mqtt.send.assert_awaited_once() + payload = client._mqtt.send.await_args.args[0] + assert b"Kitchen" in payload and b"ABCD1234" in payload + mock_exec.assert_awaited_once_with("start_cleaning") + + +async def test_clean_rooms_uses_last_map_from_monitoring(): + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(return_value=True) + client.last_map = _persisted_map() + with patch.object(client, "_execute", new_callable=AsyncMock) as mock_exec: + await client.clean_rooms(["Kitchen"], deep=True) + client._mqtt.send.assert_awaited_once() + mock_exec.assert_awaited_once_with("start_cleaning") + + +async def test_clean_rooms_without_persisted_map_raises(): + client = _make_vacuum_client_with_mocks() + with pytest.raises(SharklocalError, match="persisted map"): + await client.clean_rooms(["Kitchen"]) + + +async def test_clean_rooms_rejects_live_map(): + client = _make_vacuum_client_with_mocks() + with pytest.raises(SharklocalError, match="persisted map"): + await client.clean_rooms(["Kitchen"], vacuum_map=_persisted_map(persisted=False)) + + +async def test_clean_rooms_unknown_room_propagates_value_error(): + client = _make_vacuum_client_with_mocks() + with pytest.raises(ValueError, match="Unknown room"): + await client.clean_rooms(["Attic"], vacuum_map=_persisted_map()) + + +async def test_clean_spot_sends_pindrop_then_starts(): + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(return_value=True) + with patch.object(client, "_execute", new_callable=AsyncMock) as mock_exec: + mock_exec.return_value = True + result = await client.clean_spot(0.5, 0.5, vacuum_map=_persisted_map()) + assert result is True + assert b"PinDrop" in client._mqtt.send.await_args.args[0] + mock_exec.assert_awaited_once_with("start_cleaning") + + +async def test_clean_spot_without_map_raises(): + client = _make_vacuum_client_with_mocks() + with pytest.raises(SharklocalError, match="persisted map"): + await client.clean_spot(0.0, 0.0) + + +# --------------------------------------------------------------------------- +# _send() — MQTT-only transport for runtime-built payloads +# --------------------------------------------------------------------------- + + +async def test_send_without_mqtt_raises_action_not_supported(): + with patch("sharklocal.client.load_rest_mapping"), patch("sharklocal.client.RESTVacuumClient"): + client = VacuumClient("host", rest_mappings="test_rest_v1") + with pytest.raises(ActionNotSupportedError, match="MQTT"): + await client._send(b"\x00") + + +async def test_send_uses_pinned_mqtt_client(): + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(return_value=True) + assert await client._send(b"\x01") is True + client._mqtt.send.assert_awaited_once_with(b"\x01") + + +async def test_send_cascades_through_mqtt_candidates(): + mqtt_a = _make_mqtt_client_mock() + mqtt_a.send = AsyncMock(side_effect=ConnectError("a down")) + mqtt_b = _make_mqtt_client_mock() + mqtt_b.send = AsyncMock(return_value=True) + with patch("sharklocal.client.load_mqtt_mapping"), \ + patch("sharklocal.client.MQTTVacuumClient", side_effect=[mqtt_a, mqtt_b]): + client = VacuumClient("host", mqtt_mappings=["test_a", "test_b"]) + assert await client._send(b"\x02") is True + mqtt_a.send.assert_awaited_once() + mqtt_b.send.assert_awaited_once() + + +async def test_send_raises_last_connect_error_when_all_fail(): + client = _make_vacuum_client_with_mocks() + client._mqtt.send = AsyncMock(side_effect=ConnectError("down")) + with pytest.raises(ConnectError, match="down"): + await client._send(b"\x03") + + +# --------------------------------------------------------------------------- +# _on_monitor_status() — caches status and persisted map, forwards to callback +# --------------------------------------------------------------------------- + + +async def test_on_monitor_status_forwards_to_sync_callback_and_caches(): + client = _make_vacuum_client_with_mocks() + received: List[VacuumStatus] = [] + client.on_status_update(received.append) + status = VacuumStatus(mode=VacuumMode.CLEANING, map=_persisted_map(persisted=False)) + await client._on_monitor_status(status) + assert received == [status] + assert client.last_status is status + assert client.last_map is None # live maps are not cached as the room definition + + +async def test_on_monitor_status_forwards_to_async_callback_and_caches_persisted_map(): + client = _make_vacuum_client_with_mocks() + received: List[VacuumStatus] = [] + + async def _cb(status: VacuumStatus) -> None: + received.append(status) + + client.on_status_update(_cb) + persisted = _persisted_map() + await client._on_monitor_status(VacuumStatus(mode=VacuumMode.DOCKED, map=persisted)) + await client._on_monitor_status(VacuumStatus(mode=VacuumMode.DOCKED)) + assert len(received) == 2 + assert client.last_map is persisted # a later map-less status keeps it + + +def _job_map(*, report: bool, job_started: int) -> VacuumMap: + vacuum_map = _persisted_map() + vacuum_map.report = report + vacuum_map.job_started = job_started + return vacuum_map + + +async def test_requested_map_does_not_replace_the_report_of_the_same_job(): + client = _make_vacuum_client_with_mocks() + client.on_status_update(lambda s: None) + report = _job_map(report=True, job_started=100) + await client._on_monitor_status(VacuumStatus(mode=VacuumMode.DOCKED, map=report)) + await client._on_monitor_status( + VacuumStatus(mode=VacuumMode.DOCKED, map=_job_map(report=False, job_started=100)) + ) + assert client.last_map is report # keeps the event log + + +async def test_requested_map_of_a_newer_job_replaces_the_report(): + client = _make_vacuum_client_with_mocks() + client.on_status_update(lambda s: None) + await client._on_monitor_status( + VacuumStatus(mode=VacuumMode.DOCKED, map=_job_map(report=True, job_started=100)) + ) + requested = _job_map(report=False, job_started=200) + await client._on_monitor_status(VacuumStatus(mode=VacuumMode.DOCKED, map=requested)) + assert client.last_map is requested + + +async def test_report_replaces_a_requested_map_of_the_same_job(): + client = _make_vacuum_client_with_mocks() + client.on_status_update(lambda s: None) + await client._on_monitor_status( + VacuumStatus(mode=VacuumMode.DOCKED, map=_job_map(report=False, job_started=100)) + ) + report = _job_map(report=True, job_started=100) + await client._on_monitor_status(VacuumStatus(mode=VacuumMode.DOCKED, map=report)) + assert client.last_map is report + + +async def test_start_monitoring_wraps_callback(): + client = _make_vacuum_client_with_mocks() + client._status_callback = lambda s: None + client._mqtt.monitor = AsyncMock() + await client.start_monitoring() + await asyncio.sleep(0) + assert client._mqtt.monitor.await_args.args[0] == client._on_monitor_status + await client.stop_monitoring() diff --git a/tests/test_codes.py b/tests/test_codes.py new file mode 100644 index 0000000..7651849 --- /dev/null +++ b/tests/test_codes.py @@ -0,0 +1,132 @@ +"""Tests for sharklocal.codes and the live error/warning fields.""" + +import base64 +from pathlib import Path + +import pytest + +from sharklocal import codes, protobuf +from sharklocal.mappings import load_mqtt_mapping +from sharklocal.models import VacuumMode +from sharklocal.mqtt_client import _decode_sharkiq_protobuf_v1 + +FIXTURES = Path(__file__).parent / "fixtures" + + +def _status_frame() -> bytes: + return base64.b64decode((FIXTURES / "sharkiq_status_frame.b64").read_text().strip()) + + +def test_names_agree_with_the_event_log(): + # The log writes these as strings; the schema numbers them. + assert codes.WARNING_CODES[43] == "WARN_MM_LOWLIGHT" + assert codes.DOCK_EVENTS[7] == "DE_USR_CTR_DOCK" + assert codes.DOCK_EVENTS[8] == "DE_CLEAN_FINISH" + assert codes.SYSTEM_STATES[13] == "SYS_ST_CHARGING" + assert codes.ERROR_CODES[0] == "ERROR_NONE" + + +def test_unknown_numbers_stay_visible(): + assert codes.names(codes.WARNING_CODES, [43, 9999]) == ["WARN_MM_LOWLIGHT", "UNKNOWN_9999"] + + +def _decode(extra: bytes): + mapping = load_mqtt_mapping("sharkiq_v1") + return _decode_sharkiq_protobuf_v1(_status_frame() + extra, mapping.modes) + + +def test_a_real_status_frame_has_no_active_errors(): + status = _decode(b"") + assert status.errors == [] + assert status.warnings == [] + + +def test_packed_errors_and_warnings_are_decoded(): + packed = protobuf.encode_bytes_field(5, bytes([21, 64])) + protobuf.encode_bytes_field(6, bytes([43])) + status = _decode(packed) + assert status.errors == [21, 64] + assert codes.names(codes.ERROR_CODES, status.errors)[0] == codes.ERROR_CODES[21] + assert status.warnings == [43] + + +def test_unpacked_errors_are_decoded(): + status = _decode(protobuf.encode_varint_field(5, 64) + protobuf.encode_varint_field(5, 150)) + assert status.errors == [64, 150] + + +@pytest.mark.parametrize( + "state, mode", + [ + (3, VacuumMode.IDLE), + (4, VacuumMode.PAUSED), + (5, VacuumMode.ERROR), + (6, VacuumMode.CLEANING), + (7, VacuumMode.RETURNING_TO_DOCK), + (8, VacuumMode.CLEANING), + (13, VacuumMode.DOCKED), # charging on the dock: observed after every job + (14, VacuumMode.DOCKED), + (16, VacuumMode.CLEANING), + ], +) +def test_system_states_map_to_modes(state, mode): + assert load_mqtt_mapping("sharkiq_v1").modes[state] == mode.value + + +def _fixture_status(name: str): + mapping = load_mqtt_mapping("sharkiq_v1") + payload = base64.b64decode((FIXTURES / name).read_text().strip()) + return _decode_sharkiq_protobuf_v1(payload, mapping.modes) + + +def test_live_frame_mid_clean(): + status = _fixture_status("sharkiq_live_map_frame.b64") + assert status.state == 6 + assert status.mode == VacuumMode.CLEANING + assert status.charging is False + assert (status.fan_speed, status.brushroll_speed, status.side_brush_speed) == (82, 54, 44) + assert codes.RELOCATION_STATES[status.relocation] == "RS_SUCCESS" + # A dark basement: the live warning field reports low light. + assert codes.names(codes.WARNING_CODES, status.warnings) == ["WARN_LOW_LIGHT", "WARN_LOW_LIGHT"] + + +def test_end_of_job_frame_agrees_with_its_own_log(): + status = _fixture_status("sharkiq_persisted_map_frame.b64") + assert codes.SYSTEM_STATES[status.state] == "SYS_ST_CHARGING" + assert status.mode == VacuumMode.DOCKED + assert status.charging is True + # The live warning code and the event log's DT_WARNING_CODE name agree. + assert codes.names(codes.WARNING_CODES, status.warnings) == ["WARN_MM_LOWLIGHT"] + assert [e.code for e in status.map.log if e.key == "DT_WARNING_CODE"] == ["WARN_MM_LOWLIGHT"] + + +def test_docked_and_full(): + status = _fixture_status("sharkiq_status_frame.b64") + assert codes.SYSTEM_STATES[status.state] == "SYS_ST_BATTERY_FULL" + assert status.charging is False + assert status.battery_level == 100 + assert status.temperature == 20 + assert codes.WIFI_STATES[status.wifi_state] == "WIFI_CONNECTED" + assert status.fan_speed == 0 + + +def test_feature_toggles(): + status = _decode(protobuf.encode_varint_field(43, 1) + protobuf.encode_varint_field(44, 2)) + assert status.clean_edge is True + assert codes.CARPET_DETECT_MODES[status.carpet_detect] == "CD_AUTO" + assert _decode(protobuf.encode_varint_field(43, 2)).clean_edge is False + + +def test_mid_job_log_entries_are_decoded(): + # A real frame from a spot clean: field 34 streams event-log entries. + status = _fixture_status("sharkiq_diagnose_frame.b64") + assert status.log_entries + assert all(e.key.startswith("DT_") for e in status.log_entries) + assert any(e.key == "DT_WATER_TANK" for e in status.log_entries) + + +def test_frames_without_log_entries_say_so(): + assert _fixture_status("sharkiq_status_frame.b64").log_entries is None + garbled = protobuf.encode_bytes_field(34, b"\xff\xff") + protobuf.encode_varint_field(34, 1) + assert _decode(garbled).log_entries == [] + not_a_list = protobuf.encode_bytes_field(34, protobuf.encode_bytes_field(5, b'{"key": "x"}')) + assert _decode(not_a_list).log_entries == [] diff --git a/tests/test_compat.py b/tests/test_compat.py new file mode 100644 index 0000000..37abdf8 --- /dev/null +++ b/tests/test_compat.py @@ -0,0 +1,116 @@ +"""Tests for sharklocal.compat: the app's per-model feature rules.""" + +import pytest + +from sharklocal.compat import MODEL_FAMILIES, RV3000_MODELS, RobotProfile + + +def test_the_app_table_is_carried_whole(): + assert len(MODEL_FAMILIES) > 600 + assert MODEL_FAMILIES["RV1000A"] == "Mesa1" + + +def test_rv3000_gets_its_settings_rows_and_mask_features(): + p = RobotProfile("RV3000-001D5F7F") + assert p.classification == "Three60" + assert p.is_rv3000 and p.has_underglow_lights and p.has_button_sounds + # 0x...7F: WetDry, FanJet, AED, Series 3, Bluetooth, Lidar, Floor Detect. + assert p.has_auto_empty is True + assert p.has_fan_jet is True + assert not p.has_carpet_boost + assert RV3000_MODELS >= {"RV3000-001D5F7F"} + + +def test_opp_gets_carpet_controls_but_not_matrix(): + p = RobotProfile("RV2500HOP") + assert p.is_opp and p.has_carpet_boost and p.has_carpet_detect + assert p.has_ultra_clean is False + assert p.has_auto_empty is True + assert not p.has_underglow_lights + + +def test_random_bounce_gets_almost_nothing(): + p = RobotProfile("RV750") + assert p.classification == "RandomBounce" + assert (p.has_map, p.has_volume, p.do_not_disturb, p.has_pin_drop) == (False, False, False, False) + + +def test_spot_lidar_has_no_pin_drop(): + p = RobotProfile("RV2100AB") + assert p.has_map is True + assert p.has_pin_drop is False + assert p.has_ultra_clean is False + + +def test_prefix_letters(): + # A (not VA) = self-emptying dock; X = FanJet. + three60 = next(m for m, f in MODEL_FAMILIES.items() if f == "Three60" and "A" in m.split("-")[0] and "VA" not in m) + assert RobotProfile(three60).has_auto_empty is True + valley = next((m for m, f in MODEL_FAMILIES.items() if f.startswith("Valley") and "A" in m.split("-")[0] and "VA" not in m), None) + if valley: + assert RobotProfile(valley).has_auto_empty is False + assert RobotProfile("RV2500VA").has_auto_empty is False + assert RobotProfile("RV2000DX").has_fan_jet is True + + +def test_a_model_missing_from_the_table_is_unknown_not_false(): + # A retail SKU is not the cloud model string: family answers are unknown, + # exact product lines are simply not matched. + p = RobotProfile("RV2610BFCA") + assert not p.known + assert p.family is None and p.classification is None + assert (p.has_map, p.has_explore, p.do_not_disturb, p.has_volume, p.has_pin_drop, p.has_mopping) == (None,) * 6 + assert (p.has_underglow_lights, p.has_carpet_boost, p.is_360ez) == (False, False, False) + + +def test_a_malformed_mask_is_ignored(): + assert RobotProfile("RV3000-ZZZZZZZZ")._mask("AED") is None + + +from sharklocal.compat import ROBOT_TYPES, Capabilities, capabilities_for_model, robot_type + + +@pytest.mark.parametrize( + "model, kind", + [ + ("RV3000-001D5F7F", "rv3000"), + ("RV2500HOP", "lidar_carpet"), + ("RV2100AB", "spot_lidar"), + ("RV1000A", "map"), + ("RV750", "basic"), + ("RV1100AA", "air"), + ("RV2000DX", "lidar"), + ("RV2610BFCA", None), + ], +) +def test_every_model_falls_into_one_robot_type(model, kind): + assert robot_type(RobotProfile(model)) == kind + + +def test_every_table_model_has_a_type(): + assert {robot_type(RobotProfile(m)) for m in MODEL_FAMILIES} <= set(ROBOT_TYPES) + + +@pytest.mark.parametrize("model", sorted(MODEL_FAMILIES)) +def test_a_robot_type_answers_like_its_models(model): + # The simple configuration must agree with the app's per-model rules on + # every feature the app decides for that model. + profile = RobotProfile(model) + caps = capabilities_for_model(model) + for feature in ( + "has_map", "has_explore", "has_pin_drop", "has_ultra_clean", "has_recharge_resume", + "has_auto_empty", "has_fan_jet", "do_not_disturb", "has_volume", + "has_underglow_lights", "has_button_sounds", "has_carpet_boost", "has_carpet_detect", + ): + assert getattr(caps, feature) == bool(getattr(profile, feature)), (model, feature) + + +def test_unknown_model_has_no_capabilities(): + assert capabilities_for_model("RV2610BFCA") is None + + +def test_extras_are_asked_not_derived(): + caps = Capabilities("lidar", self_empty_dock=True, clean_edge=False) + assert caps.has_auto_empty and not caps.has_fan_jet + assert caps.has_pin_drop and caps.has_ultra_clean and caps.do_not_disturb and caps.has_volume + assert not (caps.has_underglow_lights or caps.has_carpet_boost) diff --git a/tests/test_main.py b/tests/test_main.py index f62cbfe..cad2f74 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -11,6 +11,7 @@ from sharklocal.__main__ import ( generate_markdown_report, main, + print_map, print_status, run_command, run_probe, @@ -19,7 +20,17 @@ setup_argparse, monitor_vacuum, ) -from sharklocal.models import DeviceInfo, ProbeResult, VacuumMode, VacuumStatus +from sharklocal.models import ( + DeviceInfo, + MapGrid, + MapPoint, + MapPose, + MapRoom, + ProbeResult, + VacuumMap, + VacuumMode, + VacuumStatus, +) # --------------------------------------------------------------------------- @@ -423,6 +434,19 @@ def test_main_probe_dispatch(): mock_run.assert_called_once_with("1.2.3.4") +def test_main_uses_selector_event_loop_on_windows(): + """aiomqtt is incompatible with Windows' default proactor event loop.""" + policy = MagicMock() + with patch("sys.platform", "win32"), \ + patch("sys.argv", ["sharklocal", "1.2.3.4", "--probe"]), \ + patch("sharklocal.__main__.asyncio.WindowsSelectorEventLoopPolicy", return_value=policy, create=True), \ + patch("sharklocal.__main__.asyncio.set_event_loop_policy") as set_policy, \ + patch("sharklocal.__main__.run_probe", new_callable=AsyncMock): + main() + + set_policy.assert_called_once_with(policy) + + def test_main_save_report(): """Test --save-report flag.""" results = {"host": "1.2", "model": "M1", "rest": {}, "mqtt": {}, "fw": None} @@ -663,3 +687,31 @@ async def test_run_test_logic_load_mqtt_mapping_raises(capsys): # bad_mapping should not appear in results (exception was swallowed) assert "bad_mapping" not in results["mqtt"] + + +def test_print_status_with_map_adds_map_line(capsys): + """A map-bearing status prints a second, map summary line.""" + grid = MapGrid(resolution=0.06, width=191, height=105, origin=MapPoint(-8.43, -1.41), cells=b"") + vacuum_map = VacuumMap( + grid=grid, + path=[MapPoint(0, 0), MapPoint(0.1, 0)], + poses=[MapPose(-6.27, 1.72, -2.89)], + rooms=[MapRoom(name="Bathroom", polygon=[]), MapRoom(name="Hallway", polygon=[])], + ) + status = VacuumStatus(mode=VacuumMode.CLEANING, battery_level=84, map=vacuum_map) + print_status(status) + captured = capsys.readouterr() + assert "[STATUS] Mode: cleaning" in captured.out + assert "[MAP] live map: 191x105 @ 0.06 m" in captured.out + assert "path pts: 2" in captured.out + assert "robot: (-6.27, 1.72) @ -2.89 rad" in captured.out + assert "rooms: Bathroom, Hallway" in captured.out + + +def test_print_map_persisted_without_robot_or_rooms(capsys): + grid = MapGrid(resolution=0.06, width=2, height=2, origin=MapPoint(0, 0), cells=b"") + print_map(VacuumMap(grid=grid, persisted=True)) + captured = capsys.readouterr() + assert "[MAP] persisted map: 2x2" in captured.out + assert "robot: unknown" in captured.out + assert "rooms: none" in captured.out diff --git a/tests/test_models.py b/tests/test_models.py index d69b6f8..005511a 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -4,8 +4,16 @@ from sharklocal.models import ( DeviceInfo, + MapFeature, + MapGrid, + MapPoint, + MapPose, + MapRoom, ProbeResult, + SuctionLevel, VacuumEvent, + VacuumLogEntry, + VacuumMap, VacuumMode, VacuumStatus, ) @@ -17,13 +25,13 @@ def test_vacuum_mode_all_values(): - expected = {"unknown", "cleaning", "returning_to_dock", "docking", "docked", "idle", "exploring"} + expected = {"unknown", "cleaning", "returning_to_dock", "docking", "docked", "idle", "exploring", "paused", "error"} actual = {m.value for m in VacuumMode} assert actual == expected def test_vacuum_mode_count(): - assert len(VacuumMode) == 7 + assert len(VacuumMode) == 9 def test_vacuum_mode_is_str_enum(): @@ -175,3 +183,135 @@ def test_probe_result_defaults_none(): result = ProbeResult() assert result.rest_mapping is None assert result.mqtt_mapping is None + + +# --------------------------------------------------------------------------- +# SuctionLevel +# --------------------------------------------------------------------------- + + +def test_suction_level_values(): + assert {level.value for level in SuctionLevel} == {"eco", "normal", "max"} + + +def test_suction_level_is_str_enum(): + assert SuctionLevel.MAX == "max" + + +# --------------------------------------------------------------------------- +# VacuumStatus — MQTT-only optional fields +# --------------------------------------------------------------------------- + + +def test_vacuum_status_mqtt_fields_default_none(): + status = VacuumStatus(mode=VacuumMode.IDLE) + assert status.job_active is None + assert status.deep_clean is None + assert status.recharge_resume is None + assert status.evac_resume is None + assert status.map is None + + +# --------------------------------------------------------------------------- +# MapGrid +# --------------------------------------------------------------------------- + + +def _grid(room_ids=None) -> MapGrid: + return MapGrid( + resolution=0.06, + width=2, + height=2, + origin=MapPoint(-1.0, 0.5), + cells=b"\x0f\x64\x4b\x00", + room_ids=room_ids, + ) + + +@pytest.mark.parametrize( + "value, wall, floor", + [ + (0x00, False, True), # cleaned floor + (0x0A, False, True), # floor + (0x0F, False, True), # floor + (0x19, False, True), # floor + (0x4B, False, False), # unknown + (0x5C, True, False), # wall + (0x64, True, False), # wall + ], +) +def test_map_grid_cell_classification(value, wall, floor): + assert MapGrid.is_wall(value) is wall + assert MapGrid.is_floor(value) is floor + + +def test_map_grid_cell_lookup_is_row_major(): + grid = _grid() + assert grid.cell(0, 0) == 0x0F + assert grid.cell(1, 0) == 0x64 + assert grid.cell(0, 1) == 0x4B + assert grid.cell(1, 1) == 0x00 + + +def test_map_grid_room_id_lookup(): + assert _grid().room_id(1, 1) is None + assert _grid(room_ids=b"\x01\x01\x02\x00").room_id(0, 1) == 2 + + +def test_map_grid_constants(): + assert MapGrid.UNKNOWN == 0x4B + assert MapGrid.CLEANED == 0x00 + + +def test_map_grid_counts_cleaned_cells(): + assert MapGrid.is_cleaned(0x00) is True + assert MapGrid.is_cleaned(0x0F) is False + assert _grid().cleaned_cells == 1 + + +# --------------------------------------------------------------------------- +# VacuumMap +# --------------------------------------------------------------------------- + + +def test_vacuum_map_defaults(): + vacuum_map = VacuumMap(grid=_grid()) + assert vacuum_map.path == [] + assert vacuum_map.poses == [] + assert vacuum_map.persisted is False + assert vacuum_map.rooms == [] + assert vacuum_map.features == [] + assert vacuum_map.log == [] + assert vacuum_map.robot is None + assert vacuum_map.clean_time is None + + +def test_vacuum_map_robot_is_last_pose(): + poses = [MapPose(0.0, 0.0, 0.0), MapPose(1.0, 2.0, 3.1)] + assert VacuumMap(grid=_grid(), poses=poses).robot == poses[-1] + + +def test_vacuum_map_cleaned_area_counts_cleaned_cells(): + # _grid() has one cleaned cell. + assert VacuumMap(grid=_grid()).cleaned_area == pytest.approx(0.06 * 0.06) + + +def test_vacuum_map_clean_time_sums_the_logged_clean_times(): + log = [ + VacuumLogEntry("DT_NORMAL_CLEAN_TIME", 0, "28"), + VacuumLogEntry("DT_FOLLOW_CLEAN_TIME", 0, "73"), + VacuumLogEntry("DT_ESCAPE_CLEAN_TIME", 0, "0"), + VacuumLogEntry("DT_NORMAL_DOCK_TIME", 0, "42"), + VacuumLogEntry("DT_WARNING_CODE", 0, "WARN_MM_LOWLIGHT"), + ] + assert VacuumMap(grid=_grid(), log=log).clean_time == 101 + + +def test_map_room_and_feature_and_log_entry_fields(): + room = MapRoom(name="Kitchen", polygon=[MapPoint(0, 0)]) + assert room.selected is False + assert room.coverage is None + feature = MapFeature(kind="door", points=[MapPoint(0, 0), MapPoint(1, 0)]) + assert feature.kind == "door" + entry = VacuumLogEntry(key="DT_WARNING_CODE", time=1789867008, code="WARN_MM_LOWLIGHT") + assert entry.code == "WARN_MM_LOWLIGHT" diff --git a/tests/test_mqtt_client.py b/tests/test_mqtt_client.py index 20ec77a..72bfec6 100644 --- a/tests/test_mqtt_client.py +++ b/tests/test_mqtt_client.py @@ -125,10 +125,14 @@ def test_decode_sharkiq_mode_int(mode_int, expected_mode): assert result.mode == expected_mode -def test_decode_sharkiq_charging_state_3_means_charging(): - payload = _build_status_payload(6, 3, 80) - result = _decode_sharkiq_protobuf_v1(payload, _MODES) - assert result.charging is True +def test_decode_sharkiq_charging_comes_from_the_system_state(): + # Field 9.1 is the Wi-Fi state (3 = connected), which the robot reports + # while cleaning; it was once misread as "charging on dock". + cleaning = _decode_sharkiq_protobuf_v1(_build_status_payload(6, 3, 80), _MODES) + assert cleaning.charging is False + assert cleaning.wifi_state == 3 + on_dock = _decode_sharkiq_protobuf_v1(_build_status_payload(13, 3, 80), _MODES) + assert on_dock.charging is True def test_decode_sharkiq_charging_state_0_not_charging(): @@ -157,7 +161,7 @@ def test_decode_sharkiq_battery_info_not_dict(): with patch.object(protobuf, "decode_raw", return_value={4: 6, 9: b"\xff\xff"}): result = _decode_sharkiq_protobuf_v1(b"\x00", _MODES) assert result.battery_level is None - assert result.charging is None + assert result.charging is False # cleaning, from the state def test_decode_sharkiq_raw_contains_protobuf_fields(): @@ -343,7 +347,7 @@ async def test_request_status_returns_decoded_status(mqtt_mapping): assert isinstance(result, VacuumStatus) assert result.mode == VacuumMode.CLEANING assert result.battery_level == 80 - assert result.charging is True + assert result.charging is False # --------------------------------------------------------------------------- @@ -614,14 +618,7 @@ async def test_call_aiomqtt_import_error_raises_connect_error(mqtt_mapping): """If aiomqtt cannot be imported, call() raises ConnectError.""" client = MQTTVacuumClient("host", mqtt_mapping) - original_import = __builtins__.__import__ if hasattr(__builtins__, "__import__") else __import__ - - def _failing_import(name, *args, **kwargs): - if name == "aiomqtt": - raise ImportError("No module named 'aiomqtt'") - return original_import(name, *args, **kwargs) - - with patch("builtins.__import__", side_effect=_failing_import): + with patch("sharklocal.mqtt_client.aiomqtt", None): with pytest.raises(ConnectError, match="aiomqtt is required"): await client.call("start_cleaning") @@ -635,15 +632,7 @@ async def test_request_status_aiomqtt_import_error_raises_connect_error(mqtt_map """If aiomqtt cannot be imported in _request_status, ConnectError is raised.""" client = MQTTVacuumClient("host", mqtt_mapping) - import builtins - real_import = builtins.__import__ - - def _failing_import(name, *args, **kwargs): - if name == "aiomqtt": - raise ImportError("No module named 'aiomqtt'") - return real_import(name, *args, **kwargs) - - with patch("builtins.__import__", side_effect=_failing_import): + with patch("sharklocal.mqtt_client.aiomqtt", None): with pytest.raises(ConnectError, match="aiomqtt is required"): await client._request_status("DDDD", 5.0) @@ -657,15 +646,7 @@ async def test_monitor_aiomqtt_import_error_raises_connect_error(mqtt_mapping): """If aiomqtt cannot be imported in monitor(), ConnectError is raised.""" client = MQTTVacuumClient("host", mqtt_mapping) - import builtins - real_import = builtins.__import__ - - def _failing_import(name, *args, **kwargs): - if name == "aiomqtt": - raise ImportError("No module named 'aiomqtt'") - return real_import(name, *args, **kwargs) - - with patch("builtins.__import__", side_effect=_failing_import): + with patch("sharklocal.mqtt_client.aiomqtt", None): with pytest.raises(ConnectError, match="aiomqtt is required"): await client.monitor(lambda s: None) @@ -703,3 +684,119 @@ async def test_monitor_reraises_connect_error_from_subscribe(mqtt_mapping): with patch("aiomqtt.Client", return_value=mock_ctx): with pytest.raises(ConnectError, match="broker dropped connection"): await client.monitor(lambda s: None) + + +# --------------------------------------------------------------------------- +# _decode_sharkiq_protobuf_v1 — settings, job flags and map frames +# --------------------------------------------------------------------------- + + +def test_decode_sharkiq_settings_default_when_fields_absent(): + result = _decode_sharkiq_protobuf_v1(_build_status_payload(14, 3, 100), _MODES) + assert result.recharge_resume is False + assert result.evac_resume is False + assert result.job_active is False + assert result.deep_clean is None + assert result.map is None + + +def test_decode_sharkiq_settings_reflected_by_presence(): + payload = ( + _build_status_payload(6, 3, 90) + + _field(35, 0, _varint(2)) + + _field(36, 0, _varint(2)) + + _field(45, 0, _varint(2)) + ) + result = _decode_sharkiq_protobuf_v1(payload, _MODES) + assert result.recharge_resume is True + assert result.evac_resume is True + assert result.job_active is True + + +@pytest.mark.parametrize("value, expected", [(2, False), (1, True)]) +def test_decode_sharkiq_deep_clean_from_field_40(value, expected): + payload = _build_status_payload(6, 3, 90) + _field(40, 0, _varint(value)) + assert _decode_sharkiq_protobuf_v1(payload, _MODES).deep_clean is expected + + +def _map_frame_payload(mode: int = 6) -> bytes: + """A status payload with a minimal map in field 7 (2x2 grid, one path point).""" + origin = _field(1, 5, struct.pack(" bytes: + """Return the decoded bytes of a base64 fixture captured from a real robot.""" + return base64.b64decode((FIXTURES / name).read_text().strip()) + + +def _fields(data: bytes): + return protobuf.decode_fields(data) + + +def _point_f32(x: float, y: float) -> bytes: + return protobuf.encode_bytes_field( + 1, protobuf.encode_float_field(1, x) + protobuf.encode_float_field(2, y) + ) + + +def _grid_message(width: int = 2, height: int = 2, cells: bytes = b"\x0f\x64\x4b\x00") -> bytes: + origin = protobuf.encode_float_field(1, -1.0) + protobuf.encode_float_field(2, 0.5) + return ( + protobuf.encode_float_field(1, 0.06) + + protobuf.encode_bytes_field(2, origin) + + protobuf.encode_varint_field(3, width) + + protobuf.encode_varint_field(4, height) + + protobuf.encode_bytes_field(6, cells) + ) + + +def _int16_list(values: list, scale: float = 0.002) -> bytes: + raw = struct.pack(f"<{len(values)}h", *values) + return ( + protobuf.encode_float_field(1, scale) + + protobuf.encode_varint_field(2, 2) + + protobuf.encode_bytes_field(3, raw) + ) + + +def _frame(map_fields: bytes, *, persisted: bool = False) -> dict: + frame = protobuf.encode_varint_field(4, 6) + protobuf.encode_bytes_field(FIELD_MAP, map_fields) + if persisted: + frame = protobuf.encode_varint_field(FIELD_PERSISTED_FLAG, 1) + frame + return _fields(frame) + + +# --------------------------------------------------------------------------- +# has_map / decode_map — frames without a grid +# --------------------------------------------------------------------------- + + +def test_has_map_false_without_field_7(): + assert has_map(_fields(protobuf.encode_varint_field(4, 14))) is False + + +def test_has_map_false_when_field_7_has_no_grid(): + frame = _fields(protobuf.encode_bytes_field(FIELD_MAP, protobuf.encode_varint_field(1, 1))) + assert has_map(frame) is False + + +def test_has_map_false_when_field_7_is_not_bytes(): + assert has_map({FIELD_MAP: [5]}) is False + + +def test_decode_map_returns_none_without_field_7(): + assert decode_map(_fields(protobuf.encode_varint_field(4, 14))) is None + + +def test_decode_map_returns_none_when_field_7_is_not_bytes(): + assert decode_map({FIELD_MAP: [5]}) is None + + +def test_decode_map_returns_none_without_grid(): + frame = _fields(protobuf.encode_bytes_field(FIELD_MAP, protobuf.encode_varint_field(1, 1))) + assert decode_map(frame) is None + + +# --------------------------------------------------------------------------- +# decode_map — minimal hand-built frames +# --------------------------------------------------------------------------- + + +def test_decode_grid_geometry_and_cells(): + vacuum_map = decode_map(_frame(protobuf.encode_bytes_field(5, _grid_message()))) + grid = vacuum_map.grid + assert (grid.width, grid.height) == (2, 2) + assert grid.resolution == pytest.approx(0.06) + assert (grid.origin.x, grid.origin.y) == (-1.0, 0.5) + assert grid.cells == b"\x0f\x64\x4b\x00" + assert grid.room_ids is None + assert grid.cell(1, 0) == 0x64 + assert grid.room_id(0, 0) is None + + +def test_decode_live_frame_defaults(): + vacuum_map = decode_map(_frame(protobuf.encode_bytes_field(5, _grid_message()))) + assert vacuum_map.persisted is False + assert vacuum_map.path == [] + assert vacuum_map.poses == [] + assert vacuum_map.robot is None + assert vacuum_map.dock is None + assert vacuum_map.rooms == [] + assert vacuum_map.features == [] + assert vacuum_map.log == [] + assert vacuum_map.clean_time is None + assert vacuum_map.map_id is None + assert vacuum_map.name is None + + +def test_decode_path_and_poses_scale_int16(): + # path: (100, -50) -> (0.2, -0.1); poses: (10, 20, 1570) -> heading ~ pi + fields = ( + protobuf.encode_bytes_field(5, _grid_message()) + + protobuf.encode_bytes_field(8, _int16_list([100, -50])) + + protobuf.encode_bytes_field(10, _int16_list([10, 20, 1570])) + ) + vacuum_map = decode_map(_frame(fields)) + assert vacuum_map.path == [MapPoint(pytest.approx(0.2), pytest.approx(-0.1))] + assert vacuum_map.robot.x == pytest.approx(0.02) + assert vacuum_map.robot.y == pytest.approx(0.04) + assert vacuum_map.robot.heading == pytest.approx(3.14) + + +def test_decode_ignores_trailing_partial_tuple(): + # Five int16s cannot make whole (x, y) pairs — the odd one is dropped. + fields = protobuf.encode_bytes_field(5, _grid_message()) + protobuf.encode_bytes_field( + 8, _int16_list([1, 2, 3, 4, 5]) + ) + assert len(decode_map(_frame(fields)).path) == 2 + + +def test_decode_persisted_flag_id_name_and_dock(): + dock = ( + protobuf.encode_float_field(1, -0.5) + + protobuf.encode_float_field(2, 0.25) + + protobuf.encode_float_field(3, -0.05) + ) + fields = ( + protobuf.encode_string_field(2, "unnamed") + + protobuf.encode_string_field(3, "3CDBBC59") + + protobuf.encode_bytes_field(5, _grid_message()) + + protobuf.encode_bytes_field(7, dock) + ) + vacuum_map = decode_map(_frame(fields, persisted=True)) + assert vacuum_map.persisted is True + assert vacuum_map.map_id == "3CDBBC59" + assert vacuum_map.name == "unnamed" + assert vacuum_map.dock == MapPose(-0.5, 0.25, pytest.approx(-0.05)) + + +def test_decode_room_record(): + polygon = _point_f32(0.0, 0.0) + _point_f32(1.0, 0.0) + _point_f32(1.0, 1.0) + _point_f32(0.0, 1.0) + room = ( + protobuf.encode_string_field(2, "Kitchen") + + protobuf.encode_string_field(3, "Kitchen") + + protobuf.encode_bytes_field(4, polygon) + + protobuf.encode_varint_field(5, 1) + + protobuf.encode_float_field(6, 0.5) + ) + bare = protobuf.encode_bytes_field(4, b"") + fields = ( + protobuf.encode_bytes_field(5, _grid_message()) + + protobuf.encode_bytes_field(15, room) + + protobuf.encode_bytes_field(15, bare) + ) + rooms = decode_map(_frame(fields)).rooms + assert rooms[0].name == "Kitchen" + assert rooms[0].selected is True + assert rooms[0].coverage == pytest.approx(0.5) + assert rooms[0].polygon == [MapPoint(0.0, 0.0), MapPoint(1.0, 0.0), MapPoint(1.0, 1.0), MapPoint(0.0, 1.0)] + # A record with no name, no selection and no coverage decodes to safe defaults. + assert rooms[1] == MapRoom(name="", polygon=[], selected=False, coverage=None) + + +def test_decode_features_edge_and_door_and_skips_malformed(): + polyline = _point_f32(0.0, 0.0) + _point_f32(2.0, 0.0) + edge = protobuf.encode_string_field(2, "edge") + protobuf.encode_bytes_field(4, polyline) + door = protobuf.encode_string_field(2, "door") + protobuf.encode_bytes_field(4, polyline) + no_kind = protobuf.encode_bytes_field(4, polyline) + no_points = protobuf.encode_string_field(2, "edge") + fields = protobuf.encode_bytes_field(5, _grid_message()) + for record in (edge, door, no_kind, no_points): + fields += protobuf.encode_bytes_field(28, record) + features = decode_map(_frame(fields)).features + assert [(f.kind, len(f.points)) for f in features] == [("edge", 2), ("door", 2)] + + +def test_decode_room_ids_only_when_sizes_match(): + grid = _grid_message() + matching = protobuf.encode_bytes_field(21, protobuf.encode_bytes_field(19, b"\x01\x01\x02\x00")) + wrong_size = protobuf.encode_bytes_field(21, protobuf.encode_bytes_field(19, b"\x01")) + no_raster = protobuf.encode_bytes_field(21, protobuf.encode_varint_field(1, 1)) + + with_ids = decode_map(_frame(protobuf.encode_bytes_field(5, grid) + matching)) + assert with_ids.grid.room_ids == b"\x01\x01\x02\x00" + assert with_ids.grid.room_id(0, 1) == 2 + + assert decode_map(_frame(protobuf.encode_bytes_field(5, grid) + wrong_size)).grid.room_ids is None + assert decode_map(_frame(protobuf.encode_bytes_field(5, grid) + no_raster)).grid.room_ids is None + + +def test_decode_job_start_only(): + stats = ( + protobuf.encode_varint_field(1, 1789867008) + + protobuf.encode_varint_field(3, 335) + + protobuf.encode_varint_field(6, 100) + ) + fields = protobuf.encode_bytes_field(5, _grid_message()) + protobuf.encode_bytes_field(11, stats) + vacuum_map = decode_map(_frame(fields)) + assert vacuum_map.job_started == 1789867008 + assert vacuum_map.job_minutes is None + assert not hasattr(vacuum_map, "job_duration") + + +def test_decode_job_minutes_and_clean_time_without_a_log(): + stats = protobuf.encode_varint_field(1, 1790503168) + protobuf.encode_varint_field(2, 33) + fields = protobuf.encode_bytes_field(5, _grid_message()) + protobuf.encode_bytes_field(11, stats) + vacuum_map = decode_map(_frame(fields)) + assert vacuum_map.job_minutes == 33 + assert vacuum_map.clean_time == 33 * 60 # no log: the summary's minutes + + +@pytest.mark.parametrize("map_type, persisted", [(4, True), (1, False), (2, False)]) +def test_floor_type_4_is_persisted_without_the_report_flag(map_type, persisted): + fields = protobuf.encode_varint_field(4, map_type) + protobuf.encode_bytes_field(5, _grid_message()) + vacuum_map = decode_map(_frame(fields)) + assert vacuum_map.persisted is persisted + assert vacuum_map.report is False + + +def test_report_flag_marks_a_report(): + vacuum_map = decode_map(_frame(protobuf.encode_bytes_field(5, _grid_message()), persisted=True)) + assert vacuum_map.persisted is True + assert vacuum_map.report is True + + +# --------------------------------------------------------------------------- +# decode_map — event log (field 20.3.6) +# --------------------------------------------------------------------------- + + +def _log_frame(log_field_20: bytes) -> dict: + return _frame(protobuf.encode_bytes_field(5, _grid_message()) + protobuf.encode_bytes_field(20, log_field_20)) + + +def _log_message(text: bytes) -> bytes: + return protobuf.encode_bytes_field(3, protobuf.encode_bytes_field(6, text)) + + +def test_decode_log_entries(): + entries = [ + {"key": "DT_STATE_CHANGE", "time": "1789867007s", "code": "SYS_ST_CLEANING"}, + {"key": "DT_WARNING_CODE", "time": "1789867008s", "code": "WARN_MM_LOWLIGHT"}, + {"key": "DT_VERSION_MCU", "time": "0s", "code": "Lidar2_0M1.0.91"}, + "not-a-dict", + {"key": "DT_ODD_TIME", "time": "soon", "code": "x"}, + ] + log = decode_map(_log_frame(_log_message(json.dumps(entries).encode()))).log + assert [(e.key, e.time, e.code) for e in log] == [ + ("DT_STATE_CHANGE", 1789867007, "SYS_ST_CLEANING"), + ("DT_WARNING_CODE", 1789867008, "WARN_MM_LOWLIGHT"), + ("DT_VERSION_MCU", 0, "Lidar2_0M1.0.91"), + ("DT_ODD_TIME", 0, "x"), + ] + + +def test_decode_log_tolerates_missing_or_invalid_parts(): + assert decode_map(_log_frame(protobuf.encode_varint_field(1, 1))).log == [] + assert decode_map(_log_frame(protobuf.encode_bytes_field(3, protobuf.encode_varint_field(1, 1)))).log == [] + assert decode_map(_log_frame(_log_message(b"{not json"))).log == [] + + +# --------------------------------------------------------------------------- +# decode_map — real captured frames +# --------------------------------------------------------------------------- + + +def test_empty_grid_at_job_start_is_no_map(): + # The first live frame of a job carries a grid with no resolution, size or + # cells; drawing it divided by zero. + fields = _fields(_fixture("sharkiq_empty_live_map_frame.b64")) + assert 7 in fields + assert has_map(fields) is False + assert decode_map(fields) is None + + +def test_decode_real_live_frame(): + vacuum_map = decode_map(_fields(_fixture("sharkiq_live_map_frame.b64"))) + assert vacuum_map.persisted is False + assert (vacuum_map.grid.width, vacuum_map.grid.height) == (191, 106) + assert len(vacuum_map.grid.cells) == 191 * 106 + assert vacuum_map.grid.resolution == pytest.approx(0.06, abs=1e-6) + assert len(vacuum_map.path) == 486 + assert len(vacuum_map.poses) == 254 + # Path and pose logs describe the same trajectory; both end at the robot. + assert vacuum_map.path[-1].x == pytest.approx(vacuum_map.robot.x, abs=0.2) + assert vacuum_map.path[-1].y == pytest.approx(vacuum_map.robot.y, abs=0.2) + assert vacuum_map.rooms == [] + + +def test_decode_real_persisted_frame(): + vacuum_map = decode_map(_fields(_fixture("sharkiq_persisted_map_frame.b64"))) + assert vacuum_map.persisted is True + assert vacuum_map.map_id == "3CDBBC59" + assert vacuum_map.name == "unnamed" + assert [room.name for room in vacuum_map.rooms] == ["Bathroom. ", "Room", "Laundry Room", "Hallway"] + assert vacuum_map.rooms[0].selected is True + assert vacuum_map.rooms[0].coverage == pytest.approx(0.848, abs=1e-3) + assert all(len(room.polygon) == 4 for room in vacuum_map.rooms) + assert [(f.kind, len(f.points)) for f in vacuum_map.features] == [ + ("edge", 119), ("edge", 31), ("edge", 105), ("door", 2), ("door", 2), + ] + assert vacuum_map.dock.x == pytest.approx(-0.52, abs=0.01) + assert len(vacuum_map.grid.room_ids) == len(vacuum_map.grid.cells) + assert set(vacuum_map.grid.room_ids) == {0, 1, 2, 3} + # The robot's log says 28 s normal + 73 s wall-follow cleaning. + assert vacuum_map.clean_time == 101 + assert vacuum_map.cleaned_area == pytest.approx(3.17, abs=0.01) + assert len(vacuum_map.log) == 83 + assert [e.code for e in vacuum_map.log if e.key == "DT_WARNING_CODE"] == ["WARN_MM_LOWLIGHT"] + assert vacuum_map.report is True + assert vacuum_map.job_minutes == 3 # a 216 s job, docking included + + +def test_decode_real_requested_frame(): + # The reply to request_map() while docked, after a whole-home job whose + # end-of-job frame Home Assistant missed: the same saved map with that + # job's path and summary, but no event log and no report flag. + vacuum_map = decode_map(_fields(_fixture("sharkiq_requested_map_frame.b64"))) + assert vacuum_map.persisted is True + assert vacuum_map.report is False + assert vacuum_map.map_id == "3CDBBC59" + assert [room.name for room in vacuum_map.rooms] == ["Bathroom. ", "Room", "Laundry Room", "Hallway"] + assert vacuum_map.job_started == 1790503168 + assert vacuum_map.job_minutes == 33 + assert vacuum_map.log == [] + assert vacuum_map.clean_time == 33 * 60 + assert len(vacuum_map.path) == 1671 + assert vacuum_map.cleaned_area == pytest.approx(25.61, abs=0.01) + # A whole-home run: all but 3 of its 1671 path points land on cleaned cells. + grid = vacuum_map.grid + on_cleaned = sum( + grid.cell(int((p.x - grid.origin.x) / grid.resolution), int((p.y - grid.origin.y) / grid.resolution)) + == MapGrid.CLEANED + for p in vacuum_map.path + ) + assert on_cleaned == 1668 + + +@pytest.mark.parametrize("name", ["sharkiq_live_map_frame.b64", "sharkiq_persisted_map_frame.b64"]) +def test_cleaned_cells_are_where_the_robot_went(name): + # The evidence for CLEANED = 0x00: every point of the cleaned path, in + # every captured frame, lands on a cell of that value. + vacuum_map = decode_map(_fields(_fixture(name))) + grid = vacuum_map.grid + for point in vacuum_map.path: + col = int((point.x - grid.origin.x) / grid.resolution) + row = int((point.y - grid.origin.y) / grid.resolution) + assert grid.cell(col, row) == MapGrid.CLEANED + + +def _with_saved_spot(vacuum_map: VacuumMap) -> VacuumMap: + """The map as the robot saves it after a Spot Clean (measured 2026-09-26).""" + spot = MapRoom(SPOT_ROOM_NAME, spot_polygon(2.74, 0.02), selected=True, coverage=1.0) + return dataclasses.replace(vacuum_map, rooms=[*vacuum_map.rooms, spot]) + + +def test_saved_spot_zone_is_not_a_room(persisted_map): + saved = _with_saved_spot(persisted_map) + assert saved.spot.name == SPOT_ROOM_NAME + assert saved.spot.selected is True + assert [r.name for r in saved.named_rooms] == [r.name for r in persisted_map.rooms] + assert persisted_map.spot is None + + +def test_saved_spot_zone_is_not_uploaded_with_a_room_clean(persisted_map): + saved = _with_saved_spot(persisted_map) + assert encode_room_selection(saved, ["Bathroom. "]) == _fixture("sharkiq_cmd_room_clean.b64") + with pytest.raises(ValueError, match="PinDrop"): + encode_room_selection(saved, [SPOT_ROOM_NAME]) + + +def test_new_spot_replaces_a_saved_one(persisted_map): + saved = _with_saved_spot(persisted_map) + assert encode_spot_selection(saved, 1.0, 2.0) == encode_spot_selection(persisted_map, 1.0, 2.0) + + +# --------------------------------------------------------------------------- +# encode_room_selection / encode_spot_selection +# --------------------------------------------------------------------------- + + +@pytest.fixture() +def persisted_map() -> VacuumMap: + return decode_map(_fields(_fixture("sharkiq_persisted_map_frame.b64"))) + + +def test_encode_room_selection_matches_app_capture(persisted_map): + assert encode_room_selection(persisted_map, ["Bathroom. "]) == _fixture("sharkiq_cmd_room_clean.b64") + + +def test_encode_room_selection_deep_matches_app_capture(persisted_map): + expected = _fixture("sharkiq_cmd_room_clean_matrix.b64") + assert encode_room_selection(persisted_map, ["Bathroom. "], deep=True) == expected + + +def test_map_survives_json_round_trip(persisted_map): + restored = VacuumMap.from_dict(json.loads(json.dumps(persisted_map.to_dict()))) + persisted_map.raw = {} + assert restored == persisted_map + + +def test_map_stored_before_report_existed_reads_as_a_report(persisted_map): + # Before request_map() only end-of-job reports were persisted. + stored = json.loads(json.dumps(persisted_map.to_dict())) + del stored["report"], stored["job_minutes"] + restored = VacuumMap.from_dict(stored) + assert restored.report is True + assert restored.job_minutes is None + + +def test_requested_map_survives_json_round_trip(): + requested = decode_map(_fields(_fixture("sharkiq_requested_map_frame.b64"))) + restored = VacuumMap.from_dict(json.loads(json.dumps(requested.to_dict()))) + assert (restored.report, restored.job_minutes) == (False, 33) + + +def test_stored_map_still_builds_the_app_room_command(persisted_map): + # The reason the map is stored at all: after a restart, room cleaning must + # send exactly what the app sends, from the stored copy. + restored = VacuumMap.from_dict(json.loads(json.dumps(persisted_map.to_dict()))) + expected = _fixture("sharkiq_cmd_room_clean_matrix.b64") + assert encode_room_selection(restored, ["Bathroom. "], deep=True) == expected + + +def test_encode_room_selection_lists_every_chosen_room(persisted_map): + payload = encode_room_selection(persisted_map, ["Bathroom. ", "Hallway"]) + selection = _fields(_fields(payload)[41][0]) + assert selection[1] == [b"Bathroom. ", b"Hallway"] + assert selection[3] == [b"3CDBBC59"] + assert _fields(payload)[16] == [11] + + +def test_encode_room_selection_rejects_unknown_room(persisted_map): + with pytest.raises(ValueError, match="Unknown room"): + encode_room_selection(persisted_map, ["Attic"]) + + +def test_encode_room_selection_requires_map_id(persisted_map): + persisted_map.map_id = None + with pytest.raises(ValueError, match="no id"): + encode_room_selection(persisted_map, ["Bathroom. "]) + + +def test_encode_spot_selection_appends_pindrop_room(persisted_map): + app = _fixture("sharkiq_cmd_spot_clean.b64") + app_rooms = _fields(_fields(app)[6][0])[15] + app_spot = _fields(app_rooms[-1]) + app_polygon = [_fields(p) for p in _fields(app_spot[4][0])[1]] + centre_x = sum(protobuf.float32(p[1][0]) for p in app_polygon) / 4 + centre_y = sum(protobuf.float32(p[2][0]) for p in app_polygon) / 4 + + ours = encode_spot_selection(persisted_map, centre_x, centre_y) + our_rooms = _fields(_fields(ours)[6][0])[15] + assert our_rooms[:-1] == app_rooms[:-1] + + spot = _fields(our_rooms[-1]) + assert spot[2] == [SPOT_ROOM_NAME.encode()] + assert (spot[7], spot[8], spot[9], spot[10]) == ([2], [1], [0], [2]) + corners = [_fields(p) for p in _fields(spot[4][0])[1]] + assert protobuf.float32(corners[0][1][0]) == pytest.approx(centre_x - SPOT_HALF_SIZE, abs=1e-5) + assert protobuf.float32(corners[2][2][0]) == pytest.approx(centre_y - SPOT_HALF_SIZE, abs=1e-5) + assert _fields(_fields(ours)[41][0])[1] == [SPOT_ROOM_NAME.encode()] + + +def test_encode_spot_selection_requires_map_id(persisted_map): + persisted_map.map_id = None + with pytest.raises(ValueError, match="no id"): + encode_spot_selection(persisted_map, 0.0, 0.0)